分析
这题太糟糕了,对空间的要求简直变态。上面是题外话。考虑如何求出我的兄弟们,因为兄弟和我是在同一个子树中的,所以在一个相同深度的查询,那么这个一定是一个区间。那么现在就是求一个区间的静态第 小问题。这个可以主席树维护一下。现在的做法,对每个深度开一个主席树,然后二分出来我们要查询的区间。时间复杂度为 。
代码
#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; }