[Codeforces 763A]Timofey and a tree

正解:dfs一遍然后根据边两边颜色不同乱搞。

可惜我不会。

想了想后发现,如果要求一个节点,使得所有子树纯色的话,把它搞成一个序列不就好办了。

于是就想到了欧拉序列——每一棵子树在欧拉序列上都是一段连续的空间。

那么就可以把这棵树映射到序列上了。

然后就可以暴力枚举每一个节点,然后暴力枚举所有子树了。

可以证明,这么做是O(n)的。

那么到查询了,也就是查询某段连续的区间是否完全相同(换句话说,都是一个数)。

据说可以线段树维护,可惜我写了好几遍都挂了。。

于是就搞了个分块,当然是自带剪枝的分块。

然后就水过去。。

(话说cf的数据好弱啊。。。)

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <string>
  7 #include <vector>
  8 #include <cmath>
  9 using namespace std;
 10 
 11 const int N=600000;
 12 int h[N],to[N],r[N],c[N],tot;
 13 void add(int u,int v){
 14     to[tot]=v;
 15     r[tot]=h[u];
 16     h[u]=tot++;
 17 }
 18 
 19 vector<int>dfn,color,G[N];
 20 
 21 void dfs(int x,int f){
 22     G[x].push_back(dfn.size()+1);
 23     dfn.push_back(x);
 24     color.push_back(c[x]);
 25     for(int i=h[x];i!=-1;i=r[i]){
 26         if(to[i]!=f){
 27             dfs(to[i],x);
 28             G[x].push_back(dfn.size()+1);
 29             dfn.push_back(x);
 30             color.push_back(c[x]);
 31         }
 32     }
 33 }
 34 
 35 int n;
 36 
 37 int sz,top,bl;
 38 int st[N],id[N];
 39 vector<int>bot[N];
 40 bool pure[N];
 41 void build(){
 42     for(int i=0;i<color.size();i++)st[++top]=color[i];
 43     sz=bl=sqrt(top);
 44     for(int i=1;i<=top;i++){id[i]=bot[(i-1)/sz+1].size();bot[(i-1)/sz+1].push_back(st[i]);}
 45     sz=(top-1)/bl+1;
 46     for(int i=1;i<=sz;i++){
 47         pure[i]=true;
 48         for(int j=0;j<bot[i].size();j++)
 49             if(j!=0&&bot[i][j]!=bot[i][j-1]){pure[i]=false;break;}
 50     }
 51     // for(int i=1;i<=sz;i++){
 52     //     for(int j=0;j<bot[i].size();j++){
 53     //         cout<<bot[i][j]<<' ';
 54     //     }
 55     //     cout<<endl;
 56     // }
 57 }
 58 
 59 bool isPure(int l,int r){
 60     if(l>r)return true;
 61     int lef=(l-1)/bl+1;
 62     int rig=(r-1)/bl+1;
 63     if(lef==rig){
 64         for(int i=l;i<=r;i++)
 65             if(i!=l&&st[i]!=st[i-1])return false;
 66     }else{
 67         vector<int>cls;
 68         for(int i=id[l];i<bot[lef].size();i++)cls.push_back(bot[lef][i]);
 69         for(int i=lef+1;i<=rig-1;i++){cls.push_back(bot[i][0]);if(!pure[i])return false;}
 70         for(int i=0;i<=id[r];i++)cls.push_back(bot[rig][i]);
 71         for(int i=0;i<cls.size();i++)if(i!=0&&cls[i]!=cls[i-1])return false;
 72         // for(int i=0;i<cls.size();i++)cout<<cls[i]<<' ';
 73         // cout<<endl;
 74         // printf("IDL:%d IDR:%d lef:%d rig:%d L:%d R:%d\n",id[l],id[r],lef,rig,l,r);
 75     }
 76     return true;
 77 }
 78 
 79 int main(){
 80     memset(h,-1,sizeof(h));
 81     scanf("%d",&n);
 82     for(int i=1,u,v;i<n;i++){
 83         scanf("%d%d",&u,&v);
 84         add(u,v),add(v,u);
 85     }
 86     for(int i=1;i<=n;i++)scanf("%d",&c[i]);
 87     dfs(1,0);
 88     build();
 89     // for(int i=0;i<color.size();i++)cout<<color[i]<<' ';
 90     // cout<<endl;
 91     // cout<<isPure(3,5);
 92     // return 0;
 93     for(int i=1;i<=n;i++){
 94         for(int j=0;j<G[i].size()-1;j++)
 95             if(!isPure(G[i][j]+1,G[i][j+1]-1))goto nxt;
 96         if(isPure(1,G[i][0]-1)&&isPure(G[i][G[i].size()-1]+1,dfn.size())&&color[0]==color[color.size()-1])
 97             return 0&printf("YES\n%d\n",i);
 98         nxt:;    
 99     }
100     puts("NO");
101 }
View Code

 

posted @ 2017-02-05 11:30  KingSann  阅读(222)  评论(0)    收藏  举报