bzoj2588 count on a tree 主席树

来源:互联网 发布:telnet测试 lp 端口号 编辑:程序博客网 时间:2024/05/22 06:42

在树上建主席树,每个点以它的父亲节点作为历史版本。

#include<iostream>#include<cstdio>#include<algorithm>#define maxn 200005using namespace std;struct E{    int to,nxt;}b[maxn<<1];int fst[maxn],tot=1;void build(int f,int t){    b[++tot]=(E){t,fst[f]};fst[f]=tot;    b[++tot]=(E){f,fst[t]};fst[t]=tot;}int deep[maxn];int fa[maxn][20];int w[maxn],L[maxn],len;int lca(int u,int v){    if(deep[u]>deep[v])        swap(u,v);    int t=deep[v]-deep[u];    for(int i=0;i<=17;i++)        if((t>>i)&1)    v=fa[v][i];    if(u==v) return u;    for(int i=17;i>=0;i--)        if(fa[v][i]!=fa[u][i])        {            v=fa[v][i];            u=fa[u][i];        }    return fa[u][0];}int Rt[maxn];struct zxs{    int l,r,cnt;}tree[4000005];int T=0;void insert(int l,int r,int x,int &y,int v){    y=++T;    tree[y]=tree[x];    tree[y].cnt++;    if(l==r) return;    int mid=(l+r)>>1;    if(v<=mid) insert(l,mid,tree[x].l,tree[y].l,v);    else     insert(mid+1,r,tree[x].r,tree[y].r,v);}int ask(int x,int y,int f,int k){    x=Rt[x];y=Rt[y];    int z=fa[f][0];f=Rt[f];z=Rt[z];    int l=1,r=len;    while(l<r)    {        int p=tree[tree[y].l].cnt+tree[tree[x].l].cnt;        p-=tree[tree[f].l].cnt+tree[tree[z].l].cnt;        int mid=(l+r)>>1;        if(p>=k)        {            r=mid;            x=tree[x].l;            y=tree[y].l;            f=tree[f].l;            z=tree[z].l;        }        else        {            l=mid+1;            x=tree[x].r;            y=tree[y].r;            f=tree[f].r;            z=tree[z].r;            k-=p;        }    }    return L[l];}int n,m;void dfs(int x){    for(int i=1;i<=17;i++)        fa[x][i]=fa[fa[x][i-1]][i-1];    int j=lower_bound(L+1,L+len+1,w[x])-L;    insert(1,len,Rt[fa[x][0]],Rt[x],j);    for(int i=fst[x];i;i=b[i].nxt)    {        int v=b[i].to;        if(!deep[v])        {            deep[v]=deep[x]+1;            fa[v][0]=x;            dfs(v);        }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        scanf("%d",&w[i]);        L[i]=w[i];    }    sort(L+1,L+n+1);    len=unique(L+1,L+n+1)-L-1;    int x,y,k;    for(int i=1;i<n;i++)    {        scanf("%d%d",&x,&y);        build(x,y);    }    deep[1]=1;    dfs(1);    int lst=0;    for(int i=1;i<=m;i++)    {        scanf("%d%d%d",&x,&y,&k);        x^=lst;        lst=ask(x,y,lca(x,y),k);        printf("%d",lst);        if(i!=m) puts("");    }    return 0;}
1 0
原创粉丝点击