zoukankan      html  css  js  c++  java
  • bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

    Spoj 10628. Count on a tree

    Time Limit: 12 Sec  Memory Limit: 128 MB
    Submit: 7669  Solved: 1894
    [Submit][Status][Discuss]

    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

     
    题解,可持久化权值线段树上二分即可,
    很好理解的,我自己写的runtime了好久,不知道为什么。
    改成hzwer的就过了,GG。
     
    AC代码
     
      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdio>
      6 
      7 #define N 100007
      8 #define M 2000007
      9 using namespace std;
     10 inline int read()
     11 {
     12     int x=0,f=1;char ch=getchar();
     13     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     14     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 
     18 int n,m,top,sz,ind;
     19 int a[N],zhi[N];
     20 int num[N],fx[N];
     21 int cnt,head[N],next[2*N],rea[2*N];
     22 int ls[M],rs[M],sum[M],root[N];
     23 int deep[N],fa[N][17];
     24 
     25 int find(int x)
     26 {
     27     int l=1,r=top;
     28     while(l<=r)
     29     {
     30         int mid=(l+r)>>1;
     31         if (zhi[mid]==x) return mid;
     32         if (zhi[mid]<x) l=mid+1;
     33         else r=mid-1;
     34     }
     35 }
     36 void add(int u,int v)
     37 {
     38     next[++cnt]=head[u];
     39     head[u]=cnt;
     40     rea[cnt]=v;
     41 }
     42 void dfs(int u)
     43 {
     44     ind++,num[ind]=u,fx[u]=ind;
     45     for (int i=1;i<=16;i++)
     46         fa[u][i]=fa[fa[u][i-1]][i-1];
     47     for (int i=head[u];i!=-1;i=next[i])
     48     {
     49         int v=rea[i];
     50         if (fa[u][0]!=v)
     51         {
     52             deep[v]=deep[u]+1;
     53             fa[v][0]=u;
     54             dfs(v);
     55         }
     56     }
     57 }
     58 int lca(int a,int b)
     59 {
     60     if (deep[a]<deep[b]) swap(a,b);
     61     int i;
     62     for (i=0;(1<<i)<=deep[a];i++);
     63     i--;
     64     for (int j=i;j>=0;j--)
     65         if (deep[a]-(1<<j)>=deep[b]) a=fa[a][j];
     66     if (a==b) return a;
     67     for (int j=i;j>=0;j--)
     68         if (fa[a][j]!=fa[b][j]) a=fa[a][j],b=fa[b][j];
     69     return fa[a][0];        
     70 }
     71 void change(int l,int r,int x,int &y,int z)
     72 {
     73     y=++sz;
     74     sum[y]=sum[x]+1;
     75     if (l==r) return;
     76     ls[y]=ls[x],rs[y]=rs[x];
     77     int mid=(l+r)>>1;
     78     if (z<=mid) change(l,mid,ls[x],ls[y],z);
     79     else change(mid+1,r,rs[x],rs[y],z);
     80 }
     81 int query(int l,int r,int a,int b,int c,int d,int rank)
     82 {
     83     if (l==r) return zhi[l];
     84     int mid=(l+r)>>1,tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]];
     85     if (tmp>=rank) return query(l,mid,ls[a],ls[b],ls[c],ls[d],rank);
     86     else return query(mid+1,r,rs[a],rs[b],rs[c],rs[d],rank-tmp);
     87     
     88 }
     89 int que(int x,int y,int rk)
     90 {
     91     int a=x,b=y,c=lca(x,y),d=fa[c][0];
     92     a=root[fx[a]],b=root[fx[b]],c=root[fx[c]],d=root[fx[d]];
     93     int l=1,r=top;
     94     while(l<r)
     95     {
     96         int mid=(l+r)>>1;
     97         int tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]];
     98         if(tmp>=rk)r=mid,a=ls[a],b=ls[b],c=ls[c],d=ls[d];
     99         else rk-=tmp,l=mid+1,a=rs[a],b=rs[b],c=rs[c],d=rs[d];
    100     }
    101     return zhi[l];
    102 }
    103 int main()
    104 {
    105     memset(head,-1,sizeof(head));
    106     n=read(),m=read();
    107     for (int i=1;i<=n;i++)
    108         a[i]=read(),zhi[i]=a[i];
    109     sort(zhi+1,zhi+n+1);
    110     top=1;
    111     for (int i=2;i<=n;i++)
    112         if (zhi[i]!=zhi[i-1]) zhi[++top]=zhi[i];
    113     for (int i=1;i<=n;i++)
    114         a[i]=find(a[i]);
    115     for (int i=1;i<n;i++)
    116     {
    117         int x=read(),y=read();
    118         add(x,y),add(y,x);
    119     }
    120     dfs(1);
    121     for (int i=1;i<=n;i++)
    122     {
    123         int t=num[i];//从标号的1开始。 
    124         change(1,top,root[fx[fa[t][0]]],root[i],a[t]);
    125     }
    126     int last=0;
    127     for(int i=1;i<=m;i++)
    128     {
    129         int x=read(),y=read(),rk=read();
    130         x^=last;
    131         last=que(x,y,rk);
    132         printf("%d",last);
    133         if(i!=m)printf("
    ");
    134     }
    135     /*for (int i=1;i<=m;i++)
    136     {
    137         int x=read(),y=read(),rank=read();
    138         x^=last;
    139         int a=root[fx[x]],b=root[fx[y]],c=root[fx[lca(x,y)]],d=root[fx[fa[lca(x,y)][0]]];
    140         last=query(1,top,a,b,c,d,rank);
    141         printf("%d",last);
    142         if (i!=m) cout<<endl;
    143     }*/
    144 }

    Wrong代码

      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdio>
      6 
      7 #define N 100007
      8 #define M 3000007
      9 using namespace std;
     10 inline int read()
     11 {
     12     int x=0,f=1;char ch=getchar();
     13     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     14     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 
     18 int n,m,top,sz,ind;
     19 int a[N],zhi[N];
     20 int num[N],fx[N];
     21 int cnt,head[N],next[2*N],rea[2*N];
     22 int ls[M],rs[M],sum[M],root[N];
     23 int deep[N],fa[N][17];
     24 
     25 int find(int x)
     26 {
     27     int l=1,r=top;
     28     while(l<=r)
     29     {
     30         int mid=(l+r)>>1;
     31         if (zhi[mid]==x) return mid;
     32         if (zhi[mid]<x) l=mid+1;
     33         else r=mid-1;
     34     }
     35 }
     36 void add(int u,int v)
     37 {
     38     next[++cnt]=head[u];
     39     head[u]=cnt;
     40     rea[cnt]=v;
     41 }
     42 void dfs(int u)
     43 {
     44     ind++,num[ind]=u,fx[u]=ind;
     45     for (int i=1;i<=16;i++)
     46         fa[u][i]=fa[fa[u][i-1]][i-1];
     47     for (int i=head[u];i!=-1;i=next[i])
     48     {
     49         int v=rea[i];
     50         if (fa[u][0]!=v)
     51         {
     52             deep[v]=deep[u]+1;
     53             fa[v][0]=u;
     54             dfs(v);
     55         }
     56     }
     57 }
     58 int lca(int a,int b)
     59 {
     60     if (deep[a]<deep[b]) swap(a,b);
     61     int i;
     62     for (i=0;(1<<i)<=deep[a];i++);
     63     i--;
     64     for (int j=i;j>=0;j--)
     65         if (deep[a]-(1<<j)>=deep[b]) a=fa[a][j];
     66     if (a==b) return a;
     67     for (int j=i;j>=0;j--)
     68         if (fa[a][j]!=fa[b][j]) a=fa[a][j],b=fa[b][j];
     69     return fa[a][0];        
     70 }
     71 void change(int l,int r,int x,int &y,int z)
     72 {
     73     y=++sz;
     74     sum[y]=sum[x]+1;
     75     if (l==r) return;
     76     ls[y]=ls[x],rs[y]=rs[x];
     77     int mid=(l+r)>>1;
     78     if (z<=mid) change(l,mid,ls[x],ls[y],z);
     79     else change(mid+1,r,rs[x],rs[y],z);
     80 }
     81 int query(int l,int r,int a,int b,int c,int d,int rank)
     82 {
     83     if (l==r) return zhi[l];
     84     int mid=(l+r)>>1,tmp=sum[ls[a]]+sum[ls[b]]-sum[ls[c]]-sum[ls[d]];
     85     if (tmp>=rank) return query(l,mid,ls[a],ls[b],ls[c],ls[d],rank);
     86     else return query(mid+1,r,rs[a],rs[b],rs[c],rs[d],rank-tmp);
     87 }
     88 int main()
     89 {
     90     memset(head,-1,sizeof(head));
     91     n=read(),m=read();
     92     for (int i=1;i<=n;i++)
     93         a[i]=read(),zhi[i]=a[i];
     94     sort(zhi+1,zhi+n+1);
     95     top=1;
     96     for (int i=2;i<=n;i++)
     97         if (zhi[i]!=zhi[i-1]) zhi[++top]=zhi[i];
     98     for (int i=1;i<=n;i++)
     99         a[i]=find(a[i]);
    100     for (int i=1;i<n;i++)
    101     {
    102         int x=read(),y=read();
    103         add(x,y),add(y,x);
    104     }
    105     dfs(1);
    106     for (int i=1;i<=n;i++)
    107     {
    108         int t=num[i];//从标号的1开始。 
    109         change(1,top,root[fx[fa[t][0]]],root[i],a[t]);
    110     }
    111     int last=0;
    112     for (int i=1;i<=m;i++)
    113     {
    114         int x=read(),y=read(),rank=read();
    115         x^=last;
    116         int a=root[fx[x]],b=root[fx[y]],c=root[fx[lca(x,y)]],d=root[fx[fa[lca(x,y)][0]]];
    117         last=query(1,top,a,b,c,d,rank);
    118         printf("%d",last);
    119         if (i!=m) cout<<endl;
    120     }
    121 }
  • 相关阅读:
    李开复:如何设计你的2015年度计划(转)
    深入浅出 Java 多线程(转)
    maven常见问题汇总 专题
    Introduction to the Build Lifecycle
    具体解释EBS接口开发之WIP模块接口
    Shell脚本编程具体解释
    [数字图像处理]图像去噪初步(1)--均值滤波器
    hdu-4302-Holedox Eating-线段树-单点更新,有策略的单点查询
    响应式设计:理解设备像素,CSS像素和屏幕分辨率
    #define
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8034556.html
Copyright © 2011-2022 走看看