树上启发式合并总结

学到了树上启发式合并这个东西,其实本质就是暴力,果然应了那句:世界万物皆暴力。

这是处理树上问题强有力的工具。

首先我们有三个函数 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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

posted @ 2019-10-10 16:26  小布鞋  阅读(227)  评论(0编辑  收藏  举报