2588:spoj 10628. Count on a tree time limit:12 Sec Memory limit:128 MB
submit:5217 solved:1233
[Submit] [Status] [Discuss] Description given a tree of n nodes, each point has a weight, for M queries (U,V,K), you need to answer U xor Lastans and v these two nodes K small point right. Where Lastans is the answer to the previous query, starting with 0, that is, the first query of U is clear text. Input the first row of two integer n,m. The second line has n integers, where the I integer represents the weight of the point I. The following N-1 line has two integers (x, y) per line, indicating that the point x points y has an edge. The last m row of two integers per line (u,v,k) represents a set of queries. Outputm, which represents the answer to each question. Sample Input8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2
Sample Output2
8
9
105
7
Hinthint:
n,m<=100000
Each node builds a tree of chairmen, maintaining the tree prefix and
each time between U and V is ls (u) +ls (v)-ls (LCA (U,V))-ls (Fa[lca (u,v)))Many people use the DFS sequence number, no need
Note:
1. Array Space!!!
2.lca with Tree, the order of the DFS should be heavy chain first!!!!!
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespaceStd;typedefLong Longll;Const intn=1e5+5, inf=1e9+5;intRead () {CharC=getchar ();intx=0, f=1; while(c<'0'|| C>'9'){if(c=='-') f=-1; C=GetChar ();} while(c>='0'&&c<='9') {x=x*Ten+c-'0'; C=GetChar ();} returnx*F;}intN,q,u,v,k,last,mp[n],m,w[n];structques{intU,v,k;} Q[n];intBin (intv) { intL=1, r=m; while(l<=R) { intMid= (l+r) >>1; if(MP[MID]==V)returnmid; Else if(V<mp[mid]) r=mid-1; ElseL=mid+1; } return-1;}structedge{intV,ne;} E[n<<1];intH[n],cnt;inlinevoidInsintUintv) {CNT++; E[CNT].V=v;e[cnt].ne=h[u];h[u]=CNT; CNT++; E[CNT].V=u;e[cnt].ne=h[v];h[v]=CNT;}intSize[n],fa[n],deep[n],mx[n],top[n],tid[n],tot;voidDfsintu) {Size[u]=1; for(intI=h[u];i;i=e[i].ne) { intv=e[i].v; if(V==fa[u])Continue; FA[V]=u;deep[v]=deep[u]+1; DFS (v); Size[u]+=Size[v]; if(Size[mx[u]]<size[v]) mx[u]=v; }}voidDfsintUintANC) { if(!u)return; Tid[u]=++tot; Top[u]=ANC; DFS (MX[U],ANC); for(intI=h[u];i;i=e[i].ne) { intv=e[i].v; if(v!=fa[u]&&v!=Mx[u]) DFS (V,V); }}intLcaintXinty) { while(top[x]!=Top[y]) { if(deep[top[x]]<Deep[top[y]]) swap (x, y); X=Fa[top[x]]; } if(tid[x]>Tid[y]) swap (x, y); returnx;}structnode{intL,r,size;} T[n* -];intSz,root[n];voidInsertint&x,intLintRintnum) {t[++sz]=t[x];x=sz; T[x].size++; if(L==R)return; intMid= (l+r) >>1; if(num<=mid) Insert (t[x].l,l,mid,num); ElseInsert (t[x].r,mid+1, R,num);}voidBuildintu) {Root[u]=Root[fa[u]]; Insert (Root[u],1, M,bin (W[u])); if(Mx[u]) build (Mx[u]); for(intI=h[u];i;i=e[i].ne)if(e[i].v!=fa[u]&&e[i].v!=Mx[u]) build (E[I].V);} Inlineintlsintx) {returnt[t[x].l].size;}intQueryintUintVintk) { intP=lca (u,v), q=Fa[p]; U=ROOT[U];V=ROOT[V];p =root[p];q=Root[q]; intL=1, r=m; while(l!=R) { intMid= (l+r) >>1, _=ls (U) +ls (v)-ls (p)-ls (q); if(k<=_) r=mid,u=t[u].l,v=t[v].l,p=t[p].l,q=T[Q].L; ElseL=mid+1, u=t[u].r,v=t[v].r,p=t[p].r,q=t[q].r,k-=_; } returnl;}intMain () {n=read (); q=read (); for(intI=1; i<=n;i++) mp[i]=w[i]=read (); for(intI=1; i<=n-1; i++) U=read (), v=read (), ins (u,v); DFS (1);d FS (1,1); for(intI=1; i<=q;i++) Q[i].u=read (), Q[i].v=read (), q[i].k=read (); Sort (MP+1, mp+1+N); M=1; for(intI=2; i<=n;i++)if(mp[i]!=mp[i-1]) mp[++m]=Mp[i]; Build (1); for(intI=1; i<=q;i++) {u=last^q[i].u;v=q[i].v;k=Q[I].K; Last=mp[query (u,v,k)]; printf ("%d", last); if(i!=q) Putchar ('\ n'); }}
Bzoj 2588:spoj 10628. Count on a tree [tree chair]