• 【bzoj 2588】Spoj 10628. Count on a tree


    Description

    给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

    Input

    第一行两个整数N,M。
    第二行有N个整数,其中第i个整数表示点i的权值。
    后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
    最后M行每行两个整数(u,v,k),表示一组询问。

    Output

    M行,表示每个询问的答案。最后一个询问不输出换行符

    Sample Input

    8 5
    105 2 9 3 8 5 7 7
    1 2
    1 3
    1 4
    3 5
    3 6
    3 7
    4 8
    2 5 1
    0 5 2
    10 5 3
    11 5 4
    110 8 2

    Sample Output

    2
    8
    9
    105
    7

    HINT

    N,M<=100000
    暴力自重。。。
     
     
    在树上建主席树,统计答案时为避免LCA被减两次,计算sum[x]+sum[y]-sum[lca(x,y)]-sum[fa[lca(x,y)]]。
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define LL long long
     5 using namespace std;
     6 const int N=1e5+5;
     7 int n,m,tot,x,y,rk,cnte,ind,cnt,temp,lastans;
     8 int v[N],tmp[N],first[N],id[N],num[N],root[N];
     9 int deep[N],fa[N][20];
    10 struct node{int lc,rc,sum;}tr[N*20];
    11 struct edge{int to,next;}e[N*2];
    12 int read()
    13 {
    14     int x=0,f=1;char c=getchar();
    15     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    16     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    17     return x*f;
    18 }
    19 void ins(int u,int v){e[++cnte]=(edge){v,first[u]};first[u]=cnte;}
    20 void insert(int u,int v){ins(u,v);ins(v,u);}
    21 void dfs(int x)
    22 {
    23     ind++;id[x]=ind;num[ind]=x;
    24     for(int i=1;(1<<i)<=deep[x];i++)fa[x][i]=fa[fa[x][i-1]][i-1];
    25     for(int i=first[x];i;i=e[i].next)
    26     {
    27         if(deep[e[i].to])continue;
    28         fa[e[i].to][0]=x;deep[e[i].to]=deep[x]+1;dfs(e[i].to);
    29     }
    30 }
    31 int lca(int ri,int rj)
    32 {
    33     if(deep[ri]<deep[rj])swap(ri,rj);
    34     int d=deep[ri]-deep[rj];
    35     for(int i=0;(1<<i)<=d;i++)if((1<<i)&d)ri=fa[ri][i];
    36     if(ri==rj)return ri;
    37     for(int i=17;i>=0;i--)
    38         if((1<<i)<=deep[ri]&&fa[ri][i]!=fa[rj][i])
    39             ri=fa[ri][i],rj=fa[rj][i];
    40     return fa[ri][0];
    41 }
    42 void update(int &x,int last,int L,int R,int num)
    43 {
    44     x=++cnt;tr[x].sum=tr[last].sum+1;
    45     if(L==R)return;
    46     tr[x].lc=tr[last].lc;tr[x].rc=tr[last].rc;
    47     int mid=(L+R)>>1;
    48     if(num<=mid)update(tr[x].lc,tr[last].lc,L,mid,num);
    49     else update(tr[x].rc,tr[last].rc,mid+1,R,num);
    50 }
    51 int query(int x,int y,int rk)
    52 {
    53     int a=x,b=y,c=lca(x,y),d=fa[c][0];
    54     a=root[id[x]];b=root[id[b]];c=root[id[c]];d=root[id[d]];
    55     int L=1,R=tot;
    56     while(L<R)
    57     {
    58         int mid=(L+R)>>1;
    59         temp=tr[tr[a].lc].sum+tr[tr[b].lc].sum-tr[tr[c].lc].sum-tr[tr[d].lc].sum;
    60         if(temp>=rk)R=mid,a=tr[a].lc,b=tr[b].lc,c=tr[c].lc,d=tr[d].lc;
    61         else rk-=temp,L=mid+1,a=tr[a].rc,b=tr[b].rc,c=tr[c].rc,d=tr[d].rc;
    62     }
    63     return tmp[L];
    64 }
    65 int main()
    66 {
    67     n=read();m=read();
    68     for(int i=1;i<=n;i++)v[i]=tmp[i]=read();
    69     sort(tmp+1,tmp+n+1);tot=unique(tmp+1,tmp+n+1)-tmp-1;
    70     for(int i=1;i<=n;i++)v[i]=lower_bound(tmp+1,tmp+tot+1,v[i])-tmp;
    71     for(int i=1;i<n;i++)x=read(),y=read(),insert(x,y);
    72     deep[1]=1;dfs(1);
    73     for(int i=1;i<=n;i++)
    74     {
    75         temp=num[i];
    76         update(root[i],root[id[fa[temp][0]]],1,tot,v[temp]);
    77     }
    78     for(int i=1;i<=m;i++)
    79     {
    80         x=read();y=read();rk=read();x^=lastans;
    81         lastans=query(x,y,rk);printf("%d",lastans);
    82         if(i!=m)printf("
    ");
    83     }
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    linux使用Windows中的ttf字体
    Filmic Tonemapping rocks
    Directionally Localized AntiAliasing
    OpenGL ES Emulator横向比较
    Gamma的传说
    KlayGE的Realtime GI正式上线
    CUDA 4.0真技术解析
    Antialias的前世今生(二):Post process based AA
    Antialias的前世今生(一)
    完整的“KlayGE中的延迟渲染”
  • 原文地址:https://www.cnblogs.com/zsnuo/p/8097953.html
Copyright © 2020-2023  润新知