[Agc029E]Wandering TKHS_树形dp_树上差分

Wandering TKHS

题目链接https://atcoder.jp/contests/agc029/tasks/agc029_e

数据范围:略。


题解

好神啊

Orz司队

https://www.cnblogs.com/ivorysi/p/10157002.html

代码

#include <bits/stdc++.h>

#define N 300010 

using namespace std;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
	int x = 0, f = 1;
	char c = nc();
	while (c < 48) {
		if (c == '-')
			f = -1;
		c = nc();
	}
	while (c > 47) {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x * f;
}

int head[N], to[N << 1], nxt[N << 1], tot;

inline void add(int x, int y) {
	to[ ++ tot] = y;
	nxt[tot] = head[x];
	head[x] = tot;
}

int mx[N], sz[N], d[N], c[N], son[N];

void calc(int p, int fa, int v) {
	son[p] = 1;
	for (int i = head[p]; i; i = nxt[i]) {
		if (to[i] != fa && to[i] < v) {
			calc(to[i], p, v);
			son[p] += son[to[i]];
		}
	}
}

void dfs(int p, int fa) {
	mx[p] = max(mx[fa], p);
	sz[p] = 1;
	for (int i = head[p]; i; i = nxt[i]) {
		if (to[i] != fa) {
			dfs(to[i], p);
			sz[p] += sz[to[i]], d[p] += d[to[i]];
		}
	}
	if (mx[p] == p) {
		calc(p, fa, mx[fa]);
		d[p] = -sz[p];
	}
	if (mx[fa] == fa) {
		d[p] += sz[p];
	}
}

void dfs2(int p, int fa) {
	if (fa) {
		if (mx[p] == p) {
			c[p] += son[p];
		}
		else if (mx[fa] == fa) {
			c[p] -= son[p], c[p] += d[p];
		}
		c[p] += c[fa];
	}
	for (int i = head[p]; i; i = nxt[i]) {
		if (to[i] != fa) {
			dfs2(to[i], p);
		}
	}
}

int main() {
	int n = rd();
	for (int i = 1; i < n; i ++ ) {
		int x = rd(), y = rd();
		add(x, y), add(y, x);
	}
	dfs(1,0), dfs2(1,0);
	for (int i = 2; i <= n; i ++ )
		printf("%d ", c[i]);
	return 0;
} 
posted @ 2019-10-25 11:04  JZYshuraK_彧  阅读(444)  评论(0编辑  收藏  举报