树上启发式合并总结
学到了树上启发式合并这个东西,其实本质就是暴力,果然应了那句:世界万物皆暴力。
这是处理树上问题强有力的工具。
首先我们有三个函数 dfs2,clear,insert。dfs2用于处理以该节点为根节点的子树的答案,并且保留其信息。clear为清空该子树信息,insert为插入(合并)该子树信息。
大致做法:
1、先处理出轻重儿子。
2、然后dfs2(u,fa)时,先把u的轻儿子dfs2了,然后clear它,以防止对其他子树影响。
3、dfs2重儿子,并且不用clear。
4、insert其他轻儿子。
5、加入该节点(u)信息。
6、统计答案。
按照一篇博客来刷例题(https://blog.csdn.net/pb122401/article/details/84648993)
cf375D:https://vjudge.net/problem/CodeForces-375D
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 using namespace std; 5 typedef long long ll; 6 const int N = 1e5+9; 7 vector<int> G[N]; 8 int col[N],hson[N],siz[N],num[N],sum[N]; 9 struct Query{ 10 int val,ans; 11 }q[N]; 12 vector<int> ask[N]; 13 int id,mx; 14 void dfs1(int u,int fa){ 15 // cerr<<u<<' '<<fa<<endl; 16 siz[u] = 1; hson[u] = 0; 17 for(int i = 0; i < G[u].size();++i){ 18 int v = G[u][i]; 19 if(v == fa) continue; 20 dfs1(v,u); 21 hson[u] = siz[hson[u]] > siz[v] ? hson[u] : v; 22 siz[u] += siz[v]; 23 } 24 } 25 void clear(int u,int fa){ 26 --num[col[u]]; 27 --sum[num[col[u]] + 1]; 28 for(int i = 0;i<G[u].size();++i){ 29 int v = G[u][i]; 30 if(v==fa) continue; 31 clear(v,u); 32 } 33 } 34 void insert(int u,int fa){ 35 ++num[col[u]]; 36 ++sum[ num[col[u]] ]; 37 for(int i=0;i<G[u].size();++i){ 38 int v = G[u][i]; 39 if(v==fa) continue; 40 insert(v,u); 41 } 42 } 43 void dfs2(int u,int fa){ 44 // cerr<<u<<' '<<fa<<endl; 45 for(int i = 0;i<G[u].size();++i){ 46 int v = G[u][i]; 47 if(v==fa || v==hson[u]) continue; 48 dfs2(v,u); 49 clear(v,u); 50 } 51 if(hson[u]) dfs2(hson[u],u); 52 for(int i = 0;i<G[u].size();++i){ 53 int v = G[u][i]; 54 if(v==fa || v==hson[u]) continue; 55 insert(v,u); 56 } 57 ++num[col[u]]; 58 ++sum[num[col[u]]]; 59 for(int i =0;i<ask[u].size();++i){ 60 int id = ask[u][i]; 61 q[id].ans = sum[q[id].val]; 62 // cerr<<'a'<<sum[q[id].val]<<endl; 63 } 64 } 65 int main(){ 66 int n,m; 67 scanf("%d %d",&n,&m); 68 for(int i = 1;i<=n;++i) scanf("%d",col+i); 69 for(int i = 1;i<n;++i){ 70 int u,v; scanf("%d %d",&u,&v); 71 G[u].push_back(v); 72 G[v].push_back(u); 73 // cerr<<'a'<<u<<' '<<v<<endl; 74 } 75 for(int i = 1;i<=m;++i){ 76 int u,v; scanf("%d %d",&u,&v); 77 ask[u].push_back(i); 78 q[i].val = v; 79 } 80 dfs1(1,0); 81 // cerr<<'a'<<endl; 82 dfs2(1,0); 83 for(int i = 1;i<=m;++i) printf("%d\n",q[i].ans); 84 return 0; 85 }
cf 600E:https://vjudge.net/problem/CodeForces-600E
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 using namespace std; 5 typedef long long ll; 6 const int N = 1e5+9; 7 vector<int> G[N]; 8 int col[N],hson[N],siz[N],num[N]; 9 ll sum[N]; 10 int id,mx; 11 void dfs1(int u,int fa){ 12 siz[u] = 1; hson[u] = 0; 13 for(int i = 0; i < G[u].size();++i){ 14 int v = G[u][i]; 15 if(v == fa) continue; 16 dfs1(v,u); 17 hson[u] = siz[hson[u]] > siz[v] ? hson[u] : v; 18 siz[u] += siz[v]; 19 } 20 } 21 void clear(int u,int fa){ 22 --num[col[u]]; 23 for(int i = 0;i<G[u].size();++i){ 24 int v = G[u][i]; 25 if(v==fa) continue; 26 clear(v,u); 27 } 28 } 29 void insert(int u,int fa,int p){ 30 // cerr<<u<<' '<<fa<<' '<<p<<' '<<sum[p]<<endl; 31 ++num[col[u]]; 32 if(num[col[u]] >= mx){ 33 if(num[col[u]] >mx) sum[p] = 0,id = col[u],mx=num[col[u]]; 34 sum[p] += col[u]; 35 } 36 // if(fa==1) cerr<<u<<' '<<sum[1]<<' '<<id<<' '<<mx<<'a'<<endl; 37 for(int i=0;i<G[u].size();++i){ 38 int v = G[u][i]; 39 if(v==fa) continue; 40 insert(v,u,p); 41 } 42 } 43 void dfs2(int u,int fa){ 44 // cerr<<u<<' '<<fa<<' '<<id<<endl; 45 for(int i = 0;i<G[u].size();++i){ 46 int v = G[u][i]; 47 if(v==fa || v==hson[u]) continue; 48 dfs2(v,u); 49 clear(v,u); 50 id = 0; 51 mx=0; 52 } 53 if(hson[u]){ 54 dfs2(hson[u],u),sum[u] = sum[hson[u]]; 55 // if(u==2) cerr<<id<<' '<<hson[u]<<endl; 56 // cerr<<u<<'u'<<endl; 57 } 58 // if(u==1) cerr<<u<<' '<<sum[u]<<' '<<id<<' '<<mx<<endl; 59 for(int i = 0;i<G[u].size();++i){ 60 int v = G[u][i]; 61 if(v==fa || v==hson[u]) continue; 62 insert(v,u,u); 63 // if(u==1) cerr<<v<<' '<<sum[u]<<' '<<id<<' '<<mx<<endl; 64 } 65 // if(u==1) cerr<<num[1]<<' '<<num[2]<<num[3]<<endl; 66 // if(u==1) cerr<<u<<' '<<sum[u]<<' '<<id<<' '<<mx<<endl; 67 ++num[col[u]]; 68 // if(u==1) cerr<<num[col[u]]<<endl; 69 if(num[col[u]] >= mx){ 70 if(num[col[u]] >mx) sum[u] = 0,id = col[u],mx=num[col[u]]; 71 sum[u] += col[u]; 72 } 73 } 74 int main(){ 75 int n; 76 scanf("%d",&n); 77 for(int i = 1;i<=n;++i) scanf("%d",col+i); 78 for(int i = 1;i<n;++i){ 79 int u,v; scanf("%d %d",&u,&v); 80 G[u].push_back(v); 81 G[v].push_back(u); 82 } 83 dfs1(1,0); 84 dfs2(1,0); 85 for(int i = 1;i<n;++i) printf("%lld ",sum[i]); 86 printf("%lld",sum[n]); 87 return 0; 88 }
cf570D:https://codeforces.com/problemset/problem/570/D
1 /************************************************************************* 2 > File Name: cf570D.cpp 3 # File Name: cf570D.cpp 4 # Author : xiaobuxie 5 # QQ : 760427180 6 # Email:760427180@qq.com 7 # Created Time: 2019年10月10日 星期四 15时34分47秒 8 ************************************************************************/ 9 10 #include<iostream> 11 #include<cstdio> 12 #include<map> 13 #include<cmath> 14 #include<cstring> 15 #include<set> 16 #include<queue> 17 #include<vector> 18 #include<algorithm> 19 using namespace std; 20 typedef long long ll; 21 #define inf 0x3f3f3f3f 22 #define pq priority_queue<int,vector<int>,greater<int> > 23 ll gcd(ll a,ll b){ 24 if(a<b) return gcd(b,a); 25 return b==0?a:gcd(b,a%b); 26 } 27 28 const int N = 5e5+9; 29 vector<int> G[N]; 30 vector<int> query[N]; 31 int dep[N],num[N][30],col[N],siz[N],hson[N]; 32 char s[N]; 33 int qued[N],ans[N]; 34 void dfs1(int u,int fa){ 35 //cerr<<u<<' '<<fa<<endl; 36 siz[u] = 1; hson[u] = 0; dep[u] = dep[fa] +1; 37 for(int i = 0;i<G[u].size();++i){ 38 int v = G[u][i]; 39 if(v==fa) continue; 40 dfs1(v,u); 41 siz[u] += siz[v]; 42 hson[u] = siz[hson[u]] > siz[v] ? hson[u] : v; 43 } 44 } 45 void clear(int u,int fa){ 46 num[ dep[u] ][ col[u] ] ^=1; 47 for(int i =0;i<G[u].size();++i){ 48 int v = G[u][i]; 49 if(v==fa) continue; 50 clear(v,u); 51 } 52 } 53 void insert(int u,int fa){ 54 num[ dep[u] ][col[u]] ^= 1; 55 for(int i =0;i<G[u].size();++i){ 56 int v = G[u][i]; 57 if(v==fa) continue; 58 insert(v,u); 59 } 60 } 61 void dfs2(int u,int fa){ 62 for(int i =0;i<G[u].size();++i){ 63 int v = G[u][i]; 64 if(v==fa || v==hson[u]) continue; 65 dfs2(v,u); 66 clear(v,u); 67 } 68 if(hson[u]) dfs2(hson[u],u); 69 for(int i =0;i<G[u].size();++i){ 70 int v =G[u][i]; 71 if(v==fa || v==hson[u]) continue; 72 insert(v,u); 73 } 74 num[dep[u]][col[u]] ^= 1; 75 //if(u==1) for(int j=1;j<=26;++j) cerr<<num[2][j]<<' '<<j<<endl; 76 for(int i = 0 ;i<query[u].size();++i){ 77 int cnt =0; 78 int id = query[u][i]; 79 int d = qued[id]; 80 //if(u==1) cerr<<d<<'a'<<endl; 81 for(int j =1;j<=26;++j) cnt+=num[d][j]; 82 //if(u==1) cerr<<d<<' '<<cnt<<endl; 83 ans[id] = cnt<=1? 1 : 0; 84 } 85 } 86 int main(){ 87 int n,m; scanf("%d %d",&n,&m); 88 for(int i = 2;i<=n;++i){ 89 int u; scanf("%d",&u); 90 G[u].push_back(i); 91 G[i].push_back(u); 92 } 93 scanf("%s",s); 94 for(int i = 1;i<=n;++i){ 95 col[i] = s[i-1] - 'a' + 1; 96 //cerr<<i<<' '<<col[i]<<endl; 97 } 98 for(int i = 1;i<=m;++i){ 99 int u; scanf("%d %d",&u,qued+i); 100 query[u].push_back(i); 101 } 102 //cerr<<'b'<<endl; 103 dep[0] = 0; 104 dfs1(1,0); 105 //cerr<<'a'<<endl; 106 dfs2(1,0); 107 for(int i = 1;i<=m;++i){ 108 if(ans[i]) puts("Yes"); 109 else puts("No"); 110 } 111 return 0; 112 }