分析
这题太糟糕了,对空间的要求简直变态。上面是题外话。考虑如何求出我的兄弟们,因为兄弟和我是在同一个子树中的,所以在一个相同深度的查询,那么这个一定是一个区间。那么现在就是求一个区间的静态第 小问题。这个可以主席树维护一下。现在的做法,对每个深度开一个主席树,然后二分出来我们要查询的区间。时间复杂度为
。
代码
#include<bits/stdc++.h>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
int read() {
int x = 0,f = 0;char ch = getchar();
while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();}
while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
return f ? -x : x;
}
const int N = 1e6 + 1;
vector<int> G[N],S[N];
int fa[N][20],dep[N],si[N],val[N],id[N],Id,n,lastans = 0;
int sum[N*22],lc[N*22],rc[N*22],rt[N],size,cnt,pos[N],A[N];
void dfs(int x,int Fa,int Dep) {
id[x] = ++Id;A[Id] = x;fa[x][0] = Fa;
dep[x] = Dep;si[x] = 1;
S[dep[x]].push_back(id[x]);
for(auto y:G[x]) {
if(y == Fa) continue;dfs(y,x,Dep+1);
si[x] += si[y];
}
}
int Ask(int x,int k) {
for(int i = 19;~i;i--) if((k>>i)&1) x = fa[x][i];
return x;
}
void update(int &a,int b,int l,int r,int pos) {
a = ++size;
lc[a] = lc[b];rc[a] = rc[b];sum[a] = sum[b] + 1;
if(l == r) return;
int mid = l + r >> 1;
if(pos <= mid) update(lc[a],lc[b],l,mid,pos);
else update(rc[a],rc[b],mid+1,r,pos);
}
int Query(int a,int b,int l,int r,int k) {
if(l == r) return l;
int d = sum[lc[b]] - sum[lc[a]],mid = l + r >> 1;
if(d >= k) return Query(lc[a],lc[b],l,mid,k);
else return Query(rc[a],rc[b],mid+1,r,k-d);
}
int main()
{
n = read();int Q = read();
for(int i = 1;i <= n;i++) val[i] = read();
for(int i = 1;i < n;i++) {
int a = read(),b = read();
G[a].push_back(b);G[b].push_back(a);
}
dfs(1,0,1);
for(int j = 1;j <= 19;j++){
for(int i = 1;i <= n;i++) {
fa[i][j] = fa[fa[i][j-1]][j-1];
}
}
for(int i = 1;i <= n;i++) {
for(auto x:S[i]) {
pos[x] = ++cnt;
update(rt[cnt],rt[cnt-1],1,n,val[A[x]]);
}
}
while(Q--) {
int a = (read() ^ lastans) % n + 1,k = read();
int Fa = Ask(a,k),l,r;
if(Fa == 0) {printf("?\n");continue;}
l = lower_bound(S[dep[a]].begin(),S[dep[a]].end(),id[Fa]) - S[dep[a]].begin();
r = upper_bound(S[dep[a]].begin(),S[dep[a]].end(),id[Fa]+si[Fa]-1) - S[dep[a]].begin() - 1;
if(r - l + 1 < k) {printf("?\n");continue;}
l = S[dep[a]][l];r = S[dep[a]][r];
lastans = Query(rt[pos[l]-1],rt[pos[r]],1,n,k);
printf("%d\n",lastans);
}
return 0;
}
京公网安备 11010502036488号