【BZOJ2588】【Spoj 10628.】 Count on a tree 可持久化线段树+lca
2015-04-14 22:05
477 查看
链接:
#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/45048639"); }
题解:
对于每个树上节点存一个版本的可持久化线段树,为它到根节点上所有权值的权值线段树(需要离散化)。然后对于每次询问,这条链(a,b)的线段树就是:线段树a+线段树b−线段树lca−线段树falca线段树_a + 线段树_b - 线段树_{lca} - 线段树_{fa_{lca}}
然后线段树上求第k小啦。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101000 #define LOGN 20 #define LS s[last].l #define RS s[last].r #define ls s[now].l #define rs s[now].r using namespace std; struct LSH { int x,id; void read(int i){id=i;scanf("%d",&x);} bool operator < (const LSH &a)const {return x<a.x;} }lsh ; int n,m,p; struct Eli { int v,next; }e[N<<1]; int head ,cnt,val ; inline void add(int u,int v) { e[++cnt].v=v; e[cnt].next=head[u]; head[u]=cnt; } struct Segment_Tree { int l,r,x; }s[N*LOGN]; int root ; void add(int last,int &now,int x,int L=1,int R=p) { now=++cnt; if(L==R)s[now].x=s[last].x+1; else { int mid=L+R>>1; if(x<=mid)add(LS,ls,x,L,mid),rs=RS; else add(RS,rs,x,mid+1,R),ls=LS; s[now].x=s[ls].x+s[rs].x; } } int query(int a,int b,int A,int B,int k,int L=1,int R=p) { int x=s[s[a].l].x+s[s[b].l].x-s[s[A].l].x-s[s[B].l].x; if(L==R)return L; int mid=L+R>>1; if(k<=x)return query(s[a].l,s[b].l,s[A].l,s[B].l,k,L,mid); else return query(s[a].r,s[b].r,s[A].r,s[B].r,k-x,mid+1,R); } int fa [LOGN],dep ; void dfs(int x,int p) { fa[x][0]=p; dep[x]=dep[p]+1; add(root[p],root[x],val[x]); int i,v; for(i=head[x];i;i=e[i].next) { v=e[i].v; if(v==p)continue; dfs(v,x); } } void array() { for(int k=1;k<LOGN;k++) for(int i=1;i<=n;i++) fa[i][k]=fa[fa[i][k-1]][k-1]; } int getlca(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(int k=LOGN-1;~k;k--) if(dep[fa[x][k]]>=dep[y]) x=fa[x][k]; if(x==y)return x; for(int k=LOGN-1;~k;k--) if(fa[x][k]!=fa[y][k]) x=fa[x][k],y=fa[y][k]; return fa[x][0]; } int lastans; int main() { int i,a,b,c; scanf("%d%d",&n,&m); for(i=1;i<=n;i++)lsh[i].read(i); sort(lsh+1,lsh+n+1); for(i=1;i<=n;i++) { if(i==1||lsh[i].x!=lsh[i-1].x)lsh[++p].x=lsh[i].x; val[lsh[i].id]=p; } for(cnt=0,i=1;i<n;i++) { scanf("%d%d",&a,&b); add(a,b),add(b,a); } cnt=0,dfs(1,0); array(); while(m--) { scanf("%d%d%d",&a,&b,&c),a^=lastans; i=getlca(a,b); a=query(root[a],root[b],root[i],root[fa[i][0]],c); lastans=lsh[a].x; printf("%d\n",lastans); } return 0; }
相关文章推荐
- 2588: Spoj 10628. Count on a tree[可持久化线段树+倍增lca]
- BZOJ-2588-Count-on-a-tree-SPOJ10628-LCA+主席树
- [bzoj 2588] Spoj 10628. Count on a tree:函数式线段树
- 2588: Spoj 10628. Count on a tree (可持久化线段树)
- 【bzoj2588】Spoj 10628. Count on a tree LCA+主席树
- bzoj 2588: Spoj 10628. Count on a tree LCA+主席树
- bzoj2588:Count on a tree(可持久化线段树+Lca)
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
- 【BZOJ】2588 Spoj 10628. Count on a tree LCA+主席树
- 【BZOJ2588】Spoj 10628. Count on a tree【主席树】【LCA】
- bzoj2588 Spoj 10628. Count on a tree【主席树+lca】
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
- 【bzoj 2588】Count on a tree(可持久化线段树+LCA)
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
- 2588: Spoj 10628. Count on a tree 主席树+LCA
- BZOJ2588 Spoj 10628. Count on a tree
- BZOJ 2588: Spoj 10628. Count on a tree
- bzoj2588: Spoj 10628. Count on a tree
- [BZOJ2588]Count on a tree(可持久化权值线段树|主席树)
- BZOJ 2588 Spoj 10628 Count on a tree