洛谷 P2633 Count on a tree[bzoj2588](倍增lca+主席树)
2017-09-18 18:08
495 查看
传送门
此题非常裸,就是代码太多了,2519,115行。
没什么可说的,思路就是每个节点利用它的父亲建立主席树,查询的时候,sum[u]+sum[v]-sum[lca[u]]-sum[father[lca[u,v]]]就是左子树的大小,然后就没什么了。
代码:(1000ms,还挺快的)
此题非常裸,就是代码太多了,2519,115行。
没什么可说的,思路就是每个节点利用它的父亲建立主席树,查询的时候,sum[u]+sum[v]-sum[lca[u]]-sum[father[lca[u,v]]]就是左子树的大小,然后就没什么了。
代码:(1000ms,还挺快的)
#include<cstdio> #include<algorithm> #define ll long long using namespace std; inline int read(){ int x=0;char ch=' '; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x; } struct edge{ int to,next; }e[200001]; int n,m,tot,size; int v[100001]; int b[100001]; int head[100001]; int root[100001]; int st[100001][17]; int dep[100001]; struct node{ int size,ls,rs; node(){ size=ls=rs=0; } }t[100001*30]; void build(int l,int r,int &now){ now=++tot; if(l==r)return; int mid=l+r>>1; build(l,mid,t[now].ls); build(mid+1,r,t[now].rs); } void addtree(int l,int r,int &now,int pre,int x){ now=++tot; t[now]=t[pre]; t[now].size++; if(l==r)return; int mid=l+r>>1; if(x<=mid)addtree(l,mid,t[now].ls,t[pre].ls,x); else addtree(mid+1,r,t[now].rs,t[pre].rs,x); } int query(int l,int r,int now1,int now2,int pre1,int pre2,int k){ if(l==r)return b[l]; int lsize=t[t[now1].ls].size+t[t[now2].ls].size-t[t[pre1].ls].size-t[t[pre2].ls].size; int mid=l+r>>1; if(k<=lsize)return query(l,mid,t[now1].ls,t[now2].ls,t[pre1].ls,t[pre2].ls,k); else return query(mid+1,r,t[now1].rs,t[now2].rs,t[pre1].rs,t[pre2].rs,k-lsize); } void dfs(int x,int fa){ st[x][0]=fa; dep[x]=dep[fa]+1; int num=lower_bound(b+1,b+size+1,v[x])-b; addtree(1,size,root[x],root[fa],num); for(int i=head[x];i;i=e[i].next){ int u=e[i].to; if(u==fa)continue; dfs(u,x); } } void getst(){ for(int k=1;k<=16;k++){ for(int i=1;i<=n;i++){ st[i][k]=st[st[i][k-1]][k-1]; } } } int getlca(int x,int y){ if(x==y)return x; if(dep[x]>dep[y])swap(x,y); for(int k=16;k>=0;k--){ if(dep[st[y][k]]>=dep[x]){ y=st[y][k]; } } if(x==y)return x; for(int k=16;k>=0;k--){ if(st[x][k]!=st[y][k]){ x=st[x][k]; y=st[y][k]; } } return st[x][0]; } int ask(int x,int y,int k){ int lca=getlca(x,y); int ans=query(1,size,root[x],root[y],root[lca],root[st[lca][0]],k); return ans; } inline void addedge(int x,int y){ e[++tot].to=y;e[tot].next=head[x];head[x]=tot; } int main(){ n=read();m=read(); for(int i=1;i<=n;i++){ v[i]=read();b[i]=v[i]; } sort(b+1,b+n+1); size=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n-1;i++){ int x=read(),y=read(); addedge(x,y);addedge(y,x); } tot=0; build(1,size,root[0]); dfs(1,0); getst(); int ans=0; for(int i=1;i<=m;i++){ int x=read(),y=read(),k=read(); ans=ask(x^ans,y,k); printf("%d\n",ans); } return 0; }
相关文章推荐
- BZOJ 2588 Count on a tree 主席树+倍增LCA
- 主席树+LCA【p2633 (bzoj2588】 Count on a tree
- bzoj 2588: Spoj 10628. Count on a tree LCA+主席树
- BZOJ2588 Count on a tree <DFS序+LCA+值域主席树>
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
- 【bzoj2588】Spoj 10628. Count on a tree LCA+主席树
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
- bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
- 【BZOJ 2588】Count on a tree 【树上路径第K大】【LCA+主席树】
- BZOJ 2588 Count On a Tree 【LCA】【主席树】
- 【BZOJ】2588 Spoj 10628. Count on a tree LCA+主席树
- 【BZOJ2588】Spoj 10628. Count on a tree【主席树】【LCA】
- BZOJ-2588-Count-on-a-tree-SPOJ10628-LCA+主席树
- 【BZOJ2588】Count on a tree,主席树维护链+ST表求LCA
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
- bzoj2588 Spoj 10628. Count on a tree【主席树+lca】
- [bzoj2588][count on a tree] (主席树+lca)
- 【BZOJ 2588】 Spoj 10628. Count on a tree|树上K大|树链剖分|主席树
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树