Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const int MAXN = 210000;
- struct dfs_res {
- int ans;
- int sz;
- dfs_res(int _ans, int _sz) :
- ans(_ans), sz(_sz)
- {};
- };
- int n, m;
- vector<int> g[MAXN];
- int level[MAXN];
- int parent[MAXN];
- int color[MAXN];
- int cnt[MAXN][2];
- int ans[MAXN][2];
- int contrib[MAXN][2];
- int dist[300][MAXN];
- struct centroid_decomposition {
- centroid_decomposition() {
- for (int i = 0; i < n; ++i) {
- level[i] = -1;
- parent[i] = color[i] = 0;
- }
- build(0, -1, 0, n);
- }
- dfs_res dfs1(int v, int p, int SZ, int& center) {
- int sz = 1, ans = 0;
- for (int to : g[v]) {
- if (to != p && level[to] == -1) {
- auto t = dfs1(to, v, SZ, center);
- sz += t.sz;
- ans += (t.ans + t.sz);
- }
- }
- if (center == -1 && (2 * sz > SZ || p == -1))
- center = v;
- return dfs_res(ans, sz);
- }
- dfs_res dfs2(int v, int p, int lvl, int d) {
- dist[lvl][v] = d;
- int sz = 1, ans = 0;
- for (int to : g[v]) {
- if (to != p && level[to] == -1) {
- auto t = dfs2(to, v, lvl, d + 1);
- sz += t.sz;
- ans += (t.ans + t.sz);
- }
- }
- return dfs_res(ans, sz);
- }
- void build(int v, int p, int lvl, int SZ) {
- int center = -1;
- dfs_res ans_sz = dfs1(v, -1, SZ, center);
- int t = ans_sz.ans + ans_sz.sz;
- ans_sz = dfs2(center, center, lvl, 0);
- parent[center] = p;
- ans[center][0] = ans_sz.ans;
- ans[center][1] = 0;
- cnt[center][0] = ans_sz.sz;
- cnt[center][1] = 0;
- contrib[center][0] = t;
- contrib[center][1] = 0;
- level[center] = lvl;
- for (int to : g[center])
- if (level[to] == -1)
- build(to, center, lvl + 1, SZ / 2);
- }
- void change(int v) {
- int t_v = v;
- int c = color[v];
- int n_c = (c + 1) % 2;
- color[v] = n_c;
- do {
- --cnt[v][c];
- ++cnt[v][n_c];
- if (parent[v] != -1) {
- contrib[v][c] -= dist[level[parent[v]]][t_v];
- contrib[v][n_c] += dist[level[parent[v]]][t_v];
- ans[parent[v]][c] -= dist[level[parent[v]]][t_v];
- ans[parent[v]][n_c] += dist[level[parent[v]]][t_v];
- }
- v = parent[v];
- } while (v != -1);
- }
- int get(int v) {
- int t_v = v;
- int c = color[v];
- int res = ans[v][c];
- while (parent[v] != -1) {
- res += ans[parent[v]][c] - contrib[v][c] + (cnt[parent[v]][c] - cnt[v][c]) * dist[level[parent[v]]][t_v];
- v = parent[v];
- }
- return res;
- }
- };
- void solve() {
- cin >> n >> m;
- for (int i = 0; i < n; ++i)
- g[i] = vector<int>();
- for (int i = 0; i < n - 1; ++i) {
- int u, v;
- cin >> u >> v;
- g[u - 1].push_back(v - 1);
- g[v - 1].push_back(u - 1);
- }
- centroid_decomposition cd;
- for (int i = 0; i < m; ++i) {
- int type, v;
- cin >> type >> v;
- if (type == 1) {
- cd.change(v - 1);
- } else {
- cout << cd.get(v - 1) << "\n";
- }
- }
- }
- int main() {
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement