n<=100000的点权树,有m<=100000个询问,每次问两个点间的第k小点权,保证有解,强制在线。
主席上树啦!类似于之前的序列不带修改询问的前缀表示法,现在只要把前缀当成某点到根的信息即可。然后比如要问x点和y点,z为lca(x,y),w为z的爸爸,那么x,y,z,w四棵线段树一起跑即可。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<stdlib.h> 5 //#include<iostream> 6 using namespace std; 7 8 int n,m; 9 #define maxn 100011 10 #define maxm 2000011 11 struct SMT 12 { 13 struct Node 14 { 15 int son[2]; 16 int cnt; 17 }a[maxm]; 18 int size,n; 19 void clear(int m) {n=m;size=0;a[0].cnt=0;} 20 void build(int pre,int &rt,int L,int R,int num) 21 { 22 rt=++size; 23 a[rt].cnt=a[pre].cnt+1; 24 if (L==R) {a[rt].son[0]=a[rt].son[1]=0;return;} 25 const int mid=(L+R)>>1; 26 if (num<=mid) build(a[pre].son[0],a[rt].son[0],L,mid,num),a[rt].son[1]=a[pre].son[1]; 27 else build(a[pre].son[1],a[rt].son[1],mid+1,R,num),a[rt].son[0]=a[pre].son[0]; 28 } 29 void build(int pre,int &rt,int num) {build(pre,rt,1,n,num);} 30 // void test(int x,int L,int R) 31 // { 32 // const int mid=(L+R)>>1; 33 // if (a[x].son[0]) test(a[x].son[0],L,mid); 34 //// cout<<L<<' '<<R<<' '<<a[x].cnt<<endl; 35 // if (a[x].son[1]) test(a[x].son[1],mid+1,R); 36 // } 37 // void test(int x) {test(x,1,n);} 38 }smt; 39 40 struct Edge{int to,next;}edge[maxn<<1];int first[maxn],le=2; 41 void in(int x,int y) {Edge &e=edge[le];e.to=y;e.next=first[x];first[x]=le++;} 42 void insert(int x,int y) {in(x,y);in(y,x);} 43 44 int a[maxn],b[maxn],lb; 45 int fa[maxn][22],dep[maxn],rt[maxn]; 46 void dfs(int x,int f) 47 { 48 fa[x][0]=f;dep[x]=dep[f]+1; 49 for (int j=1;j<=18;j++) 50 fa[x][j]=fa[fa[x][j-1]][j-1]; 51 smt.build(rt[f],rt[x],a[x]); 52 for (int i=first[x];i;i=edge[i].next) 53 { 54 const Edge &e=edge[i];if (e.to==f) continue; 55 dfs(e.to,x); 56 } 57 } 58 void pre() {dfs(1,0);} 59 60 int lca(int x,int y) 61 { 62 if (dep[x]<dep[y]) {int t=x;x=y;y=t;} 63 for (int i=18;i>=0;i--) if (dep[fa[x][i]]>=dep[y]) x=fa[x][i]; 64 if (x==y) return x; 65 for (int i=18;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; 66 return fa[x][0]; 67 } 68 69 int main() 70 { 71 scanf("%d%d",&n,&m); 72 for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i]; 73 lb=n;sort(b+1,b+1+lb);lb=unique(b+1,b+1+lb)-b-1; 74 for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+1+lb,a[i])-b; 75 76 smt.clear(lb); 77 for (int i=1,x,y;i<n;i++) 78 { 79 scanf("%d%d",&x,&y); 80 insert(x,y); 81 } 82 pre(); 83 // for (int i=1;i<=n;i++) smt.test(rt[i]),cout<<endl; 84 int last=0; 85 for (int i=1,x,y,K;i<=m;i++) 86 { 87 scanf("%d%d%d",&x,&y,&K); 88 x^=last; 89 int z=lca(x,y),w=fa[z][0],L=1,R=lb,tmp; 90 // cout<<x<<' '<<y<<' '<<z<<' '<<w<<endl; 91 x=rt[x];y=rt[y];z=rt[z];w=rt[w]; 92 while (L<R) 93 { 94 if ((tmp=smt.a[smt.a[x].son[0]].cnt+smt.a[smt.a[y].son[0]].cnt 95 -smt.a[smt.a[z].son[0]].cnt-smt.a[smt.a[w].son[0]].cnt)>=K) 96 x=smt.a[x].son[0],y=smt.a[y].son[0],z=smt.a[z].son[0],w=smt.a[w].son[0],R=(L+R)>>1; 97 else x=smt.a[x].son[1],y=smt.a[y].son[1],z=smt.a[z].son[1],w=smt.a[w].son[1],K-=tmp,L=((L+R)>>1)+1; 98 // cout<<tmp<<' '<<K<<endl; 99 } 100 printf("%d",(last=b[L])); 101 if (i<m) puts(""); 102 } 103 return 0; 104 }