• BZOJ2588: Spoj 10628. Count on a tree


    2588: Spoj 10628. Count on a tree

    Time Limit: 12 Sec  Memory Limit: 128 MB
    Submit: 1795  Solved: 371
    [Submit][Status]

    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




    HINT:

    N,M<=100000

    暴力自重。。。

    Source

    题解:
    感觉很好写。
    想快一点于是写了离线的tarjan 求LCA,写完了发现bzoj强制在线T_T
    代码:(应该有bug,因为没评测。。。)
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 500+100
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 struct edge{int go,next;}e[2*maxn];
    32 int n,m,tot,cnt,u[maxn],v[maxn],rk[maxn],a[maxn],id[maxn],b[maxn],fa[maxn],head[maxn];
    33 int sum[maxm],ls[maxm],rs[maxm],lca[maxn],root[maxn];
    34 vector<pa>q[maxn];
    35 bool vis[maxn];
    36 inline void insert(int x,int y)
    37 {
    38     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;
    39     e[++tot].go=x;e[tot].next=head[y];head[y]=tot;
    40 }
    41 void update(int l,int r,int x,int &y,int v)
    42 {
    43     y=++cnt;
    44     sum[y]=sum[x]+1;
    45     if(l==r)return;
    46     ls[y]=ls[x];rs[y]=rs[x];
    47     int mid=(l+r)>>1;
    48     if(v<=mid)update(l,mid,ls[x],ls[y],v);else update(mid+1,r,rs[x],rs[y],v);
    49 }
    50 inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    51 void dfs(int x)
    52 {
    53     vis[x]=1;
    54     for(int i=head[x],y;i;i=e[i].next)
    55      if(!vis[y=e[i].go])
    56       {
    57           update(1,n,root[x],root[y],b[y]);
    58           dfs(y);
    59           fa[y]=x;
    60       }
    61     int t=q[x].size();
    62     for0(i,t-1)if(vis[q[x][i].first])lca[q[x][i].second]=find(x);
    63 }
    64 inline bool cmp(int x,int y){return a[x]<a[y];}
    65 int main()
    66 {
    67     freopen("input.txt","r",stdin);
    68     freopen("output.txt","w",stdout);
    69     n=read();m=read();
    70     for1(i,n)a[i]=read(),id[i]=i;
    71     sort(id+1,id+n+1,cmp);
    72     for1(i,n)b[id[i]]=i;
    73     for1(i,n-1)insert(read(),read());
    74     for1(i,m)
    75      {
    76          u[i]=read();v[i]=read();rk[i]=read();
    77          q[u[i]].push_back(pa(v[i],i));
    78          q[v[i]].push_back(pa(u[i],i));
    79      }
    80     for1(i,n)fa[i]=i; 
    81     update(1,n,0,root[1],b[1]);
    82     dfs(1);
    83     int ans=0;
    84     for1(i,m)
    85      {
    86         int x=root[u[i]],y=root[v[i]],xx=root[lca[i]],yy=root[fa[lca[i]]],l=1,r=n,k=rk[i];
    87         while(l!=r)
    88         {
    89             int t=sum[ls[x]]+sum[ls[y]]-sum[ls[xx]]-sum[ls[yy]],mid=(l+r)>>1;
    90             if(t>=k){x=ls[x];y=ls[y];xx=ls[xx];yy=ls[yy];r=mid;}
    91             else {x=rs[x];y=rs[y];xx=rs[xx];yy=rs[yy];l=mid+1;k-=t;}
    92         }
    93         ans=l;
    94         printf("%d
    ",a[id[ans]]);
    95      }
    96     return 0;
    97 }
    View Code

    在线的话其实没多大区别

    直接在dfs的时候就可以把主席树、LCA的预处理做出来,然后就OK了。
    代码:(刚开始没更新1RE了5.6次。。。)
      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<iostream>
      7 #include<vector>
      8 #include<map>
      9 #include<set>
     10 #include<queue>
     11 #include<string>
     12 #define inf 1000000000
     13 #define maxn 100000+1000
     14 #define maxm 2000000+1000
     15 #define eps 1e-10
     16 #define ll long long
     17 #define pa pair<int,int>
     18 #define for0(i,n) for(int i=0;i<=(n);i++)
     19 #define for1(i,n) for(int i=1;i<=(n);i++)
     20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     22 #define mod 1000000007
     23 using namespace std;
     24 inline int read()
     25 {
     26     int x=0,f=1;char ch=getchar();
     27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     29     return x*f;
     30 }
     31 struct edge{int go,next;}e[2*maxn];
     32 int n,m,tot,cnt,a[maxn],id[maxn],b[maxn],head[maxn];
     33 int sum[maxm],ls[maxm],rs[maxm],root[maxn],f[maxn][18],dep[maxn];
     34 bool vis[maxn];
     35 inline void insert(int x,int y)
     36 {
     37     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;
     38     e[++tot].go=x;e[tot].next=head[y];head[y]=tot;
     39 }
     40 void update(int l,int r,int x,int &y,int v)
     41 {
     42     y=++cnt;
     43     sum[y]=sum[x]+1;
     44     if(l==r)return;
     45     ls[y]=ls[x];rs[y]=rs[x];
     46     int mid=(l+r)>>1;
     47     if(v<=mid)update(l,mid,ls[x],ls[y],v);else update(mid+1,r,rs[x],rs[y],v);
     48 }
     49 void dfs(int x)
     50 {
     51     for1(i,17)
     52      if((1<<i)<=dep[x])f[x][i]=f[f[x][i-1]][i-1];else break;
     53     for(int i=head[x],y;i;i=e[i].next)
     54      if(!dep[y=e[i].go])
     55       {
     56           dep[y]=dep[x]+1;f[y][0]=x;
     57         update(1,n,root[x],root[y],b[y]);
     58           dfs(y);
     59       }
     60 }
     61 int lca(int x,int y)
     62 {
     63     if(dep[x]<dep[y])swap(x,y);
     64     int t=dep[x]-dep[y];
     65     for0(i,17)
     66      if(t&(1<<i))x=f[x][i];
     67     if(x==y)return x;
     68     for3(i,17,0)
     69      if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
     70     return f[x][0];
     71 }
     72 inline bool cmp(int x,int y){return a[x]<a[y];}
     73 int main()
     74 {
     75     freopen("input.txt","r",stdin);
     76     freopen("output.txt","w",stdout);
     77     n=read();m=read();
     78     for1(i,n)a[i]=read(),id[i]=i;
     79     sort(id+1,id+n+1,cmp);
     80     for1(i,n)b[id[i]]=i;
     81     for1(i,n-1)insert(read(),read());
     82     insert(0,1);
     83     dep[0]=1;
     84     dfs(0);
     85     int ans=0;
     86     for1(i,m)
     87      {
     88          
     89         int x=read()^ans,y=read(),xx=lca(x,y),yy=f[xx][0],k=read(),l=1,r=n;
     90         x=root[x];y=root[y];xx=root[xx];yy=root[yy];
     91         while(l!=r)
     92         {
     93             int t=sum[ls[x]]+sum[ls[y]]-sum[ls[xx]]-sum[ls[yy]],mid=(l+r)>>1;
     94             if(t>=k){x=ls[x];y=ls[y];xx=ls[xx];yy=ls[yy];r=mid;}
     95             else {x=rs[x];y=rs[y];xx=rs[xx];yy=rs[yy];l=mid+1;k-=t;}
     96         }
     97         ans=a[id[l]];
     98         printf("%d",ans);
     99         if(i!=m)printf("
    ");
    100      }
    101     return 0;
    102 }
    View Code

    这貌似和dfs序没什么关系啊。。。

    主席树维护的是点x到根的权值情况。

     
  • 相关阅读:
    Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)
    终于有人把“TCC分布式事务”实现原理讲明白了
    Java synchronized 关键字的实现原理
    Synchronized的实现原理(汇总)
    Spring的Bean的生命周期(大众版)
    Synchronized与Lock的区别与应用场景
    Lock与synchronized 的区别
    线程的同步控制synchronized和lock的对比和区别
    lock和synchronized的同步区别与选择
    Mybatis3.x与Spring4.x整合
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4006207.html
Copyright © 2020-2023  润新知