zoukankan      html  css  js  c++  java
  • [bzoj4771]七彩树

    首先考虑没有深度限制,即对一颗子树求颜色数,那么可以用树上差分,根据dfs序,每个点和这个颜色在dfs中上一次出现点的lca-1,然后每个点再打上一个+1,然后求一颗子树内所有节点的标记和即为答案。

    为了深度限制,因此可以以深度为时间建一棵可持久化线段树,然后查询(x,d)即查询第deep[x]+d层的以x为根的子树,同时过程中可以维护当前插入的节点中每一个颜色的set(根据dfs排序)来处理lca的加减。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 100001
      4 #define mid (l+r>>1)
      5 struct ji{
      6     int nex,to;
      7 }edge[N<<1];
      8 int E,V,t,n,m,x,y,k,sz[N],c[N],r[N],sh[N],head[N],out[N],in[N],df[N],ndf[N],f[N][21],ls[N*100],rs[N*100],tr[N*100];
      9 set<int>se[N];
     10 struct node{
     11     int d,id; 
     12 }a[N];
     13 bool cmp(node  x,node y){
     14     return x.d<y.d; 
     15 }
     16 void add(int x,int y){
     17     edge[E].nex=head[x];
     18     edge[E].to=y;
     19     head[x]=E++;
     20 }
     21 void dfs(int k,int s){
     22     sz[k]=1;
     23     sh[k]=s;
     24     ndf[df[k]=++df[0]]=k;
     25     in[k]=++x;
     26     for(int i=head[k];i!=-1;i=edge[i].nex){
     27         dfs(edge[i].to,s+1);
     28         sz[k]+=sz[edge[i].to];
     29     }
     30     out[k]=++x;
     31 }
     32 bool pd(int x,int y){
     33     return (in[x]<=in[y])&&(out[y]<=out[x]);
     34 }
     35 int lca(int x,int y){
     36     if (pd(x,y))return x;
     37     if (pd(y,x))return y;
     38     for(int j=20;j>=0;j--)
     39         if (!pd(f[x][j],y))x=f[x][j];
     40     return f[x][0];
     41 }
     42 void update(int k1,int &k2,int l,int r,int x,int y){
     43     if ((x<l)||(x>r)||(l>r))return;
     44     tr[k2=++V];  
     45     ls[k2]=rs[k2]=0; 
     46     if (l==r){
     47         tr[k2]=tr[k1]+y;
     48         return;
     49     }
     50     update(ls[k1],ls[k2]=ls[k1],l,mid,x,y);
     51     update(rs[k1],rs[k2]=rs[k1],mid+1,r,x,y);
     52     tr[k2]=tr[ls[k2]]+tr[rs[k2]];
     53 }
     54 int query(int k,int l,int r,int x,int y){
     55     if ((x>r)||(l>y)||(l>r))return 0;
     56     if ((x<=l)&&(r<=y))return tr[k];
     57     return query(ls[k],l,mid,x,y)+query(rs[k],mid+1,r,x,y);
     58 }
     59 int main(){
     60     scanf("%d",&t);
     61     while (t--){
     62         scanf("%d%d",&n,&m);
     63         for(int i=1;i<=n;i++)scanf("%d",&c[i]);
     64         memset(head,-1,sizeof(head));
     65         E=V=df[0]=0;
     66         memset(r,0,sizeof(r));  
     67         for(int i=2;i<=n;i++){
     68             scanf("%d",&x);
     69             add(f[i][0]=x,i);
     70         }
     71         dfs(1,1); 
     72         f[1][0]=1; 
     73         for(int j=1;j<=20;j++)
     74             for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
     75         for(int i=1;i<=n;i++) a[i].id=i,a[i].d=sh[i];  
     76         sort(a+1,a+n+1,cmp);
     77         for(int i=1;i<=n;i++)se[i].clear();
     78         for(int i=1;i<=n;i++){
     79             k=a[i].id;  
     80             update(r[sh[a[i-1].id]],r[sh[k]],1,n,df[k],1);
     81             x=y=0;
     82             set<int>::iterator it=se[c[k]].lower_bound(df[k]);
     83             if (it!=se[c[k]].end())x=ndf[*it];
     84             if (it!=se[c[k]].begin())y=ndf[*(--it)];
     85             if (x)update(r[sh[k]],r[sh[k]],1,n,df[lca(x,k)],-1);
     86             if (y)update(r[sh[k]],r[sh[k]],1,n,df[lca(y,k)],-1);
     87             if ((x)&&(y))update(r[sh[k]],r[sh[k]],1,n,df[lca(x,y)],1);
     88             se[c[k]].insert(df[k]);
     89         }
     90         k=0;
     91         for(int i=1;i<=n;i++) if(!r[i]) r[i]=r[i-1];  
     92         while (m--){
     93             scanf("%d%d",&x,&y);
     94             x^=k;
     95             y^=k;  
     96             y=min(y+sh[x],n);  
     97             printf("%d\n",k=query(r[y],1,n,df[x],df[x]+sz[x]-1));
     98         }
     99     }
    100 }
    View Code
  • 相关阅读:
    pat 甲级 1065. A+B and C (64bit) (20)
    pat 甲级 1064. Complete Binary Search Tree (30)
    pat 甲级 1010. Radix (25)
    pat 甲级 1009. Product of Polynomials (25)
    pat 甲级 1056. Mice and Rice (25)
    pat 甲级 1078. Hashing (25)
    pat 甲级 1080. Graduate Admission (30)
    pat 甲级 团体天梯 L3-004. 肿瘤诊断
    pat 甲级 1099. Build A Binary Search Tree (30)
    Codeforce 672B. Different is Good
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249947.html
Copyright © 2011-2022 走看看