dsu+长链剖分
Posted ytytzzz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dsu+长链剖分相关的知识,希望对你有一定的参考价值。
dsu,对于无修改子树查询,并且操作支持undo的问题
暴力dfs,对于每个节点,对所有轻儿子dfs下去,然后再消除轻儿子的影响
dfs重儿子,然后dfs暴力恢复轻儿子们的影响,再把当前节点影响算进去
就有了整棵子树的信息了,时间复杂度O(nlogn)
经典例题:http://codeforces.com/contest/600/problem/E
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 7 const int N = 1e5 + 5; 8 9 int n, c[N]; 10 11 int cnt[N], maxCnt; 12 13 int siz[N], son[N]; 14 15 vector <int> e[N]; 16 17 ll ans[N], sum[N]; 18 19 void dfs1(int u, int fr) 20 siz[u] = 1; 21 for (int v : e[u]) 22 if (v == fr) continue; 23 dfs1(v, u); 24 siz[u] += siz[v]; 25 if (siz[v] > siz[son[u]]) son[u] = v; 26 27 28 29 void update(int x, int y) 30 sum[cnt[x]] -= x; 31 cnt[x] += y; 32 sum[cnt[x]] += x; 33 if (cnt[x] > maxCnt) maxCnt = cnt[x]; 34 if (sum[maxCnt] == 0) maxCnt --; 35 36 37 void dfs3(int u, int fr, int val) 38 update(c[u], val); 39 for (int v : e[u]) 40 if (v == fr) continue; 41 dfs3(v, u, val); 42 43 44 45 void dfs2(int u, int fr) 46 for (int v : e[u]) 47 if (v == fr || v == son[u]) continue; 48 dfs2(v, u), dfs3(v, u, -1); 49 50 if (son[u]) dfs2(son[u], u); 51 for (int v : e[u]) 52 if (v == fr || v == son[u]) continue; 53 dfs3(v, u, 1); 54 55 update(c[u], 1); 56 ans[u] = sum[maxCnt]; 57 58 59 int main() 60 ios::sync_with_stdio(false); 61 cin >> n; 62 for (int i = 1; i <= n; i ++) 63 cin >> c[i]; 64 for (int u, v, i = 1; i < n; i ++) 65 cin >> u >> v; 66 e[u].push_back(v); 67 e[v].push_back(u); 68 69 dfs1(1, 1), dfs2(1, 1); 70 for (int i = 1; i <= n; i ++) 71 cout << ans[i] << ‘ ‘; 72 cout << endl; 73 return 0; 74
以上是关于dsu+长链剖分的主要内容,如果未能解决你的问题,请参考以下文章