树上用主席树的话,对每个点到根的区间开个线段树
然后每次询问求出lca后就能用区间减法了(链剖的代码还是挺好看的)
弄了好久只是空间的问题,开空间也不能太随意。。
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 200000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar(); 15 return x*f; 16 } 17 struct edge{ 18 int t,v; 19 edge *next; 20 }e[2*NM],*h[NM],*_o=e,*null; 21 void add(int x,int y){ 22 _o++;_o->t=y;_o->next=h[x];h[x]=_o; 23 } 24 struct node{ 25 int s; 26 node *l,*r; 27 }T[20*NM],*root[NM],*o=T; 28 int d[NM],f[NM],top[NM],son[NM],size[NM],TOP; 29 int n,m,_t,cnt,a[NM],b[NM],_x,_y,_p; 30 node* mod(node *p,int x,int y){ 31 int t=x+y>>1;node *r=++o; 32 *o=*p;r->s++; 33 if(x==y)return r; 34 if(_t<=t)r->l=mod(p->l,x,t); 35 else r->r=mod(p->r,t+1,y); 36 return r; 37 } 38 void dfs1(int x){ 39 _t=a[x];root[x]=mod(root[f[x]],1,cnt); 40 link(x) 41 if(!d[j->t]){ 42 f[j->t]=x;d[j->t]=d[x]+1; 43 dfs1(j->t); 44 size[x]+=size[j->t]; 45 if(size[j->t]>size[son[x]])son[x]=j->t; 46 } 47 size[x]++; 48 } 49 void dfs2(int x){ 50 top[x]=TOP; 51 if(son[x])dfs2(son[x]); 52 link(x)if(!top[j->t])dfs2(TOP=j->t); 53 } 54 int lca(int x,int y){ 55 if(top[x]==top[y])return d[x]<d[y]?x:y; 56 return d[top[x]]>d[top[y]]?lca(f[top[x]],y):lca(x,f[top[y]]); 57 } 58 int query(node *r1,node *r2,node *r3,node *r4,int x,int y,int k){ 59 int t=x+y>>1,v=r1->l->s+r2->l->s-r3->l->s-r4->l->s; 60 if(x==y)return b[x]; 61 if(k<=v)return query(r1->l,r2->l,r3->l,r4->l,x,t,k); 62 else return query(r1->r,r2->r,r3->r,r4->r,t+1,y,k-v); 63 } 64 int main(){ 65 freopen("data.in","r",stdin); 66 n=read();m=read(); 67 inc(i,1,n)b[i]=a[i]=read(); 68 sort(b+1,b+n+1); 69 cnt=unique(b+1,b+n+1)-b-1; 70 inc(i,1,n)a[i]=lower_bound(b+1,b+cnt+1,a[i])-b; 71 inc(i,1,n-1){ 72 _x=read();_y=read(); 73 add(_x,_y);add(_y,_x); 74 } 75 d[1]++;root[0]=++o;root[0]->l=o;root[0]->r=o; 76 dfs1(1); 77 // inc(i,1,n)printf("%d ",son[i]);printf("\n"); 78 dfs2(TOP=1); 79 // inc(i,0,n)printf("%d ",root[i]->s);printf("\n"); 80 while(m--){ 81 _x=read()^_p;_y=read();_t=read(); 82 _p=lca(_x,_y); 83 _p=query(root[_x],root[_y],root[_p],root[f[_p]],1,cnt,_t); 84 printf("%d",_p);if(m)putchar(‘\n‘); 85 } 86 return 0; 87 }
时间: 2024-10-07 04:12:08