【bzoj 2588】Count on a tree(可持久化线段树+LCA)
2018-02-20 23:37
453 查看
传送门biu~
树上每个节点建一棵权值线段树记录这个点到根的所有点的权值,根据父节点可持久化。
查询(a,b)时,查询的是“线段树a+线段树b-线段树lca(a,b)-线段树father[lca(a,b)]”,在权值线段树上求第k小即可。
树上每个节点建一棵权值线段树记录这个点到根的所有点的权值,根据父节点可持久化。
查询(a,b)时,查询的是“线段树a+线段树b-线段树lca(a,b)-线段树father[lca(a,b)]”,在权值线段树上求第k小即可。
#include<bits/stdc++.h> using namespace std; const int N=100005,inf=~0u>>1; int n,m,ans,a ,dep ,fa [18]; int head ,nex[2*N],to[2*N],tp; struct Node{ Node *ch[2]; int sum; Node(); inline void maintain(){ sum=0; if(ch[0]) sum+=ch[0]->sum; if(ch[1]) sum+=ch[1]->sum; } }*null=new Node,*root ; Node :: Node(){ ch[0]=ch[1]=null; sum=0; } void buildtree(Node *&o,Node *u,int l,int r,int x){ o=new Node; if(l==r){ o->sum=u->sum+1; return; } int mid=1ll*l+r>>1; if(x<=mid) buildtree(o->ch[0],u->ch[0],l,mid,x),o->ch[1]=u->ch[1]; else buildtree(o->ch[1],u->ch[1],mid+1,r,x),o->ch[0]=u->ch[0]; o->maintain(); } int Query(Node *a,Node *b,Node *c,Node *d,int l,int r,int k){ if(l==r) return r; int mid=1ll*l+r>>1; int sum=a->ch[0]->sum+b->ch[0]->sum-c->ch[0]->sum-d->ch[0]->sum; if(sum>=k) return Query(a->ch[0],b->ch[0],c->ch[0],d->ch[0],l,mid,k); else return Query(a->ch[1],b->ch[1],c->ch[1],d->ch[1],mid+1,r,k-sum); } inline void add(int x,int y){ nex[++tp]=head[x]; head[x]=tp; to[tp]=y; } void dfs(int x){ dep[x]=dep[fa[x][0]]+1; buildtree(root[x],root[fa[x][0]],-inf,inf,a[x]); for(int i=head[x];i;i=nex[i]){ if(to[i]==fa[x][0]) continue; fa[to[i]][0]=x; dfs(to[i]); } } inline int lca(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(int i=17;i>=0;--i) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i]; if(x==y) return x; for(int i=17;i>=0;--i){ int xn=fa[x][i],yn=fa[y][i]; if(xn!=yn) x=xn,y=yn; } return fa[x][0]; } int main(){ null->ch[0]=null->ch[1]=null; root[0]=new Node; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<n;++i){ int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); } dfs(1); for(int j=1;j<=17;++j) for(int i=1;i<=n;++i) fa[i][j]=fa[fa[i][j-1]][j-1]; while(m--){ int a,b,c,d,k; scanf("%d%d%d",&a,&b,&k); a^=ans;c=lca(a,b);d=fa[c][0]; ans=Query(root[a],root[b],root[c],root[d],-inf,inf,k); printf("%d",ans); if(m)puts(""); } return 0; }
相关文章推荐
- bzoj2588:Count on a tree(可持久化线段树+Lca)
- 【BZOJ2588】【Spoj 10628.】 Count on a tree 可持久化线段树+lca
- [BZOJ2588]Count on a tree(可持久化权值线段树|主席树)
- 2588: Spoj 10628. Count on a tree[可持久化线段树+倍增lca]
- 【bzoj2588】Spoj 10628. Count on a tree LCA+主席树
- 主席树+LCA【p2633 (bzoj2588】 Count on a tree
- 【BZOJ 2588】Count on a tree 【树上路径第K大】【LCA+主席树】
- BZOJ 2588 Count On a Tree 【LCA】【主席树】
- BZOJ 2588 Count on a tree (COT) 可持久化线段树
- 洛谷 P2633 Count on a tree[bzoj2588](倍增lca+主席树)
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
- BZOJ-2588-Count-on-a-tree-SPOJ10628-LCA+主席树
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
- [bzoj2588][count on a tree] (主席树+lca)
- 2588: Spoj 10628. Count on a tree (可持久化线段树)
- 【BZOJ2588】Count on a tree,主席树维护链+ST表求LCA
- BZOJ2588 Count on a tree <DFS序+LCA+值域主席树>
- bzoj 2588: Spoj 10628. Count on a tree LCA+主席树
- 【BZOJ】2588 Spoj 10628. Count on a tree LCA+主席树
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )