bzoj4448 情报传递

题目链接

离线+树上主席树,主席树维护时间标记

注意查询时如果c<0要把c赋为0;

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<string>
  5 #include<cstring>
  6 #include<cmath>
  7 #define re(i,l,r) for(int i=(l);i<=(r);i++)
  8 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 
  9 using namespace std;
 10 template <typename Q>
 11 void inin(Q &ret)
 12 {
 13     ret=0;int f=0;char ch=getchar();
 14     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
 15     while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
 16     ret=f?-ret:ret; 
 17 }
 18 const int xxx=200020;
 19 int n,fa[xxx],w[xxx],head[xxx<<1],next[xxx<<1],zhi[xxx<<1],ed;
 20 void add(int a,int b)
 21 {
 22     next[++ed]=head[a],head[a]=ed,zhi[ed]=b;
 23     next[++ed]=head[b],head[b]=ed,zhi[ed]=a;
 24 }
 25 namespace pou
 26 {
 27     int top[xxx],shen[xxx],son[xxx];
 28     int dfs(int x)
 29     {
 30         int ret=1,temp,Max=0;
 31         for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x])
 32         {
 33             shen[zhi[i]]=shen[x]+1,fa[zhi[i]]=x;
 34             temp=dfs(zhi[i]);ret+=temp;
 35             if(Max<temp)Max=temp,son[x]=zhi[i];
 36         }
 37         return ret;
 38     }
 39     void dfs(int x,int t)
 40     {
 41         if(!x)return ;
 42         top[x]=t;
 43         dfs(son[x],t);
 44         for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x]&&zhi[i]!=son[x])
 45             dfs(zhi[i],zhi[i]);
 46     }
 47     int lca(int x,int y)
 48     {
 49         while(top[x]!=top[y])
 50             if(shen[top[x]]>shen[top[y]])x=fa[top[x]];
 51             else y=fa[top[y]];
 52         return shen[x]<shen[y]?x:y;
 53     }
 54 }
 55 namespace pst
 56 {
 57     int root[xxx],sum[xxx<<4],ed,ch[xxx<<4][2];
 58     void update(int l,int r,int L,int &R,int x)
 59     {
 60         R=++ed;sum[R]=sum[L]+(x?1:0);
 61         if(!x){ch[R][0]=ch[L][0],ch[R][1]=ch[L][1];return ;}
 62         if(l==r)return ;
 63         int mid=(l+r)>>1;
 64         if(x<=mid)ch[R][1]=ch[L][1],update(l,mid,ch[L][0],ch[R][0],x);
 65         else ch[R][0]=ch[L][0],update(mid+1,r,ch[L][1],ch[R][1],x);
 66     }
 67     void build(int x)
 68     {
 69         update(1,n,root[fa[x]],root[x],w[x]);
 70         for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x])
 71             build(zhi[i]);
 72     }
 73     int query(int l,int r,int x,int c)
 74     {
 75         if(c==0)return 0;
 76         if(l>=1&&r<=c)return sum[x];
 77         int mid=(l+r)>>1;
 78         if(c<=mid)return query(l,mid,ch[x][0],c);
 79         else return query(l,mid,ch[x][0],c)+query(mid+1,r,ch[x][1],c);
 80     }
 81 }
 82 struct que
 83 {
 84     int x,y,c;
 85 }sta[200020];int top;
 86 int main()
 87 {
 88     inin(n);
 89     re(i,1,n)
 90     {
 91         int x;inin(x);
 92         if(x)add(i,x);
 93     }pou::shen[1]=1;
 94     pou::dfs(1);
 95     pou::dfs(1,1);
 96     int q;inin(q);
 97     re(i,1,q)
 98     {
 99         int opt,x,y,c;inin(opt),inin(x);
100         if(opt==1)inin(y),inin(c),sta[++top]=(que){x,y,i-c-1};
101         else w[x]=w[x]?w[x]:i;
102     }
103     pst::build(1);
104     re(i,1,top)
105     {
106         using namespace pou;
107         using namespace pst;
108         int temp=lca(sta[i].x,sta[i].y),x=sta[i].x,y=sta[i].y,c=sta[i].c;if(c<0)c=0;
109         printf("%d ",shen[sta[i].x]+shen[sta[i].y]-(shen[temp]<<1)+1);
110         printf("%d\n",query(1,n,root[x],c)+query(1,n,root[y],c)-2*query(1,n,root[fa[temp]],c)-(w[temp]<=c&&w[temp]>0));
111     }
112     return 0;
113 }

 

posted @ 2016-03-29 20:36  HugeGun  阅读(316)  评论(0编辑  收藏  举报