[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 }