BZOJ[2588]Count on a tree 主席树
2018-03-12 10:18
393 查看
传送门ber~
每个点到根这一段区间建一棵主席树
那么两点x,yx,y之间的信息可以表示为sumx+sumy−sumLCA(x,y)−sumfa[LCA(x,y)]sumx+sumy−sumLCA(x,y)−sumfa[LCA(x,y)]
这样就兹瓷第kk大了
代码如下:
每个点到根这一段区间建一棵主席树
那么两点x,yx,y之间的信息可以表示为sumx+sumy−sumLCA(x,y)−sumfa[LCA(x,y)]sumx+sumy−sumLCA(x,y)−sumfa[LCA(x,y)]
这样就兹瓷第kk大了
代码如下:
#include<algorithm> #include<ctype.h> #include<cstdio> #define N 100050 using namespace std; inline int read(){ int x=0,f=1;char c; do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c)); do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c)); return x*f; } int n,m,x,y,k,t,top,tot,las; int fir ,a ,b ,f [21],dep ; struct Edge{ int to,nex; Edge(int _=0,int __=0):to(_),nex(__){} }nex[N<<1]; struct Node{ Node *ls,*rs; int sum; Node(); inline void maintain(){ sum=ls->sum+rs->sum; return; } }*root ,*null; Node::Node():ls(null),rs(null),sum(0){} inline void init(){ null=new Node; null->ls=null->rs=null; null->sum=0; root[0]=null; return; } inline void add(int x,int y){ nex[++top]=Edge(y,fir[x]); fir[x]=top; } void Add(int L,int R,int x,Node *&k,Node *pre){ if(k==null) k=new Node; if(L==R){ k->sum=pre->sum+1; return; } int mid=L+R>>1; if(x<=mid){ Add(L,mid,x,k->ls,pre->ls); k->rs=pre->rs; } else{ Add(mid+1,R,x,k->rs,pre->rs); k->ls=pre->ls; } k->maintain(); return; } void dfs(int x,int fa,int Dep){ f[x][0]=fa;dep[x]=Dep; Add(1,tot,a[x],root[x]=null,root[fa]); for(int i=fir[x];i;i=nex[i].nex){ if(nex[i].to==fa) continue; dfs(nex[i].to,x,Dep+1); } } inline int LCA(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(int i=19;~i;i--) if(dep[f[x][i]]>=dep[y]) x=f[x][i]; if(x==y) return x; for(int i=19;~i;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } int Query(int L,int R,int k,Node *x,Node *y,Node *lca,Node *flca){ if(L==R) return L; int sum=x->ls->sum+y->ls->sum-lca->ls->sum-flca->ls->sum; int mid=L+R>>1; if(sum>=k) return Query(L,mid,k,x->ls,y->ls,lca->ls,flca->ls); else return Query(mid+1,R,k-sum,x->rs,y->rs,lca->rs,flca->rs); } int main(){ init(); n=read();m=read(); for(int i=1;i<=n;i++) b[i]=a[i]=read(); sort(b+1,b+n+1); tot=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+tot+1,a[i])-b; for(int i=1;i<n;i++){ x=read();y=read(); add(x,y);add(y,x); } dfs(1,0,1); for(int j=1;j<=19;j++) for(int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; for(int i=1;i<=m;i++){ x=read()^las;y=read();k=read(); t=LCA(x,y); las=b[Query(1,tot,k,root[x],root[y],root[t],root[f[t][0]])]; printf(i==m?"%d":"%d\n",las); } return 0; }
相关文章推荐
- 【BZOJ 2588】 Spoj 10628. Count on a tree|树上K大|树链剖分|主席树
- BZOJ2588 Count on a tree <DFS序+LCA+值域主席树>
- 【BZOJ2588】Count On a Tree(主席树)
- bzoj 2588: Spoj 10628. Count on a tree(树上主席树)
- [BZOJ2588][Spoj10628]Count on a tree(树上主席树)
- [BZOJ 2588][SPOJ COT]Count On a Tree(DFS序主席树)
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
- BZOJ 2588 Spoj 10628 Count on a tree | 树上主席树
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
- bzoj 2588 Spoj 10628. Count on a tree(主席树)
- BZOJ 2588 Count on a tree 主席树
- 【树上主席树】BZOJ2588-Count on a tree
- BZOJ.2588.Count on a tree(主席树 静态树上第k小)
- 【BZOJ2588】Count on a tree,主席树维护链+ST表求LCA
- bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】
- BZOJ 2588 Count On a Tree 【LCA】【主席树】
- BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树
- [bzoj2588][Spoj10628]Count on a tree_主席树
- BZOJ-2588-Count-on-a-tree-SPOJ10628-LCA+主席树
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )