$n leq 200000$的树,有点权,给$m leq 200000$个询问,每次问$x,k$,$x$向上走$k$步到的点的子树内和$x$同层的,除了$x$以外的点的点权众数。
询问挂点上,全图搜一次。每层开个线段树,合并的时候保留孩子里最长的一个,其他的暴力并过来。
复杂度:看起来是启发式合并但是只有一个$log$的。因为合并操作只会进行最多$n-1$次(菊花树)。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 //#include<math.h> 5 //#include<queue> 6 #include<vector> 7 #include<algorithm> 8 //#include<iostream> 9 //#include<assert.h> 10 using namespace std; 11 12 int n,m; 13 #define maxn 200011 14 15 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2; 16 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;} 17 18 struct Ques{int id,d,x,next;}ques[maxn]; int fques[maxn],lq=2; 19 void inque(int x,int id,int d,int y) 20 {Ques &e=ques[lq]; e.id=id; e.d=d; e.x=y; e.next=fques[x]; fques[x]=lq++;} 21 22 struct SMT 23 { 24 struct Node 25 { 26 int ls,rs; 27 int Max,cnt; 28 }a[maxn*18]; 29 int size,n; 30 void clear(int m) {n=m; size=0;} 31 void up(int x) 32 { 33 Node &b=a[x]; 34 if (a[b.ls].cnt>a[b.rs].cnt) {b.Max=a[b.ls].Max; b.cnt=a[b.ls].cnt;} 35 else {b.Max=a[b.rs].Max; b.cnt=a[b.rs].cnt;} 36 } 37 void modify(int &x,int L,int R,int v,int type) 38 { 39 (!x && (x=++size)); 40 if (L==R) {a[x].cnt+=type; a[x].ls=a[x].rs=0; if (a[x].cnt) a[x].Max=v; else a[x].Max=0; return;} 41 int mid=(L+R)>>1; 42 if (v<=mid) modify(a[x].ls,L,mid,v,type); else modify(a[x].rs,mid+1,R,v,type); 43 up(x); 44 } 45 void modify(int &rt,int v,int type) {modify(rt,1,n,v,type);} 46 int combine(int x,int y,int L,int R) 47 { 48 if (!x || !y) return x^y; 49 if (L==R) {a[x].cnt+=a[y].cnt; if (a[x].cnt) a[x].Max=L; else a[x].Max=0; return x;} 50 int mid=(L+R)>>1; 51 a[x].ls=combine(a[x].ls,a[y].ls,L,mid); 52 a[x].rs=combine(a[x].rs,a[y].rs,mid+1,R); 53 up(x); return x; 54 } 55 int combine(int x,int y) {return combine(x,y,1,n);} 56 }t; 57 58 int fa[20][maxn],dep[maxn]; 59 void predfs(int x,int f) 60 { 61 dep[x]=dep[f]+1; fa[0][x]=f; 62 for (int i=first[x];i;i=edge[i].next) 63 { 64 Edge &e=edge[i]; if (e.to==f) continue; 65 predfs(e.to,x); 66 } 67 } 68 void makefa() 69 { 70 for (int j=1;j<=18;j++) 71 for (int i=1;i<=n;i++) 72 fa[j][i]=fa[j-1][fa[j-1][i]]; 73 } 74 int jump(int x,int k) 75 { 76 for (int j=0;k;k>>=1,j++) if (k&1) x=fa[j][x]; 77 return x; 78 } 79 80 int val[maxn],lisa[maxn],li=0; 81 82 vector<int> v[maxn]; int len=0; 83 int root[maxn],vid[maxn],ans[maxn]; 84 void combine(int x,int y) 85 { 86 int i=v[x].size()-1,j=v[y].size()-1; 87 while (j>=0) 88 { 89 v[x][i]=t.combine(v[x][i],v[y][j]); 90 i--; j--; 91 } 92 } 93 void dfs(int x) 94 { 95 int Max=0; 96 for (int i=first[x];i;i=edge[i].next) 97 { 98 Edge &e=edge[i]; if (e.to==fa[0][x]) continue; 99 dfs(e.to); if (v[vid[e.to]].size()>v[vid[Max]].size()) Max=e.to; 100 } 101 t.modify(root[x],val[x],1); 102 if (Max) 103 { 104 vid[x]=vid[Max]; 105 for (int i=first[x];i;i=edge[i].next) 106 { 107 Edge &e=edge[i]; if (e.to==fa[0][x] || e.to==Max) continue; 108 combine(vid[Max],vid[e.to]); 109 } 110 v[vid[x]].push_back(root[x]); 111 } 112 else {len++; vid[x]=len; v[len].push_back(root[x]);} 113 114 for (int i=fques[x];i;i=ques[i].next) 115 { 116 Ques &e=ques[i]; 117 int p=v[vid[x]].size()-e.d-1,now=v[vid[x]][p]; 118 t.modify(now,val[e.x],-1); 119 if (t.a[now].Max==0) ans[e.id]=-1; 120 else ans[e.id]=lisa[t.a[now].Max]; 121 t.modify(now,val[e.x],1); 122 } 123 } 124 125 int qread() 126 { 127 char c; int s=0; while ((c=getchar())<'0' || c>'9'); 128 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s; 129 } 130 int main() 131 { 132 n=qread(); int root; 133 for (int i=1,x;i<=n;i++) {x=qread(); if (x) in(x,i); else root=i;} 134 predfs(root,0); makefa(); 135 136 for (int i=1;i<=n;i++) val[i]=qread(),lisa[i]=val[i]; 137 li=n; sort(lisa+1,lisa+1+n); li=unique(lisa+1,lisa+1+n)-lisa-1; 138 for (int i=1;i<=n;i++) val[i]=lower_bound(lisa+1,lisa+1+li,val[i])-lisa; 139 t.clear(li); 140 141 m=qread(); 142 for (int i=1,x,y;i<=m;i++) 143 { 144 x=qread(); y=qread(); 145 int z=jump(x,y); 146 if (z) inque(z,i,y,x); else ans[i]=-1; 147 } 148 dfs(root); 149 for (int i=1;i<=m;i++) printf(ans[i]==-1?"ZYPRESSEN ":"%d ",ans[i]); 150 return 0; 151 }