1. 程式人生 > >【BZOJ4719】【NOIP2016】天天愛跑步

【BZOJ4719】【NOIP2016】天天愛跑步

【題目連結】

【思路要點】

  • 補檔部落格,無題解。

【程式碼】

#include<bits/stdc++.h>
using namespace std;
#define MAXN	300005
#define MAXV	600005
#define MAXLOG	20
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
vector <int> a[MAXN], b[MAXN], c[MAXN];
int t[MAXN], vb[MAXN], vc[MAXN], ans[MAXN];
int depth[MAXN], father[MAXN][MAXLOG];
int hb[MAXV], hc[MAXV];
void dfs(int pos, int fa) {
	depth[pos] = depth[fa] + 1;
	father[pos][0] = fa;
	for (int i = 1; i < MAXLOG; i++)
		father[pos][i] = father[father[pos][i - 1]][i - 1];
	for (unsigned i = 0; i < a[pos].size(); i++)
		if (a[pos][i] != fa) dfs(a[pos][i], pos);
}
int lca(int x, int y) {
	if (depth[x] < depth[y]) swap(x, y);
	for (int i = MAXLOG - 1; i >= 0; i--)
		if (depth[father[x][i]] >= depth[y]) x = father[x][i];
	if (x == y) return x;
	for (int i = MAXLOG - 1; i >= 0; i--)
		if (father[x][i] != father[y][i]) {
			x = father[x][i];
			y = father[y][i];
		}
	return father[x][0];
}
void work(int pos, int fa) {
	int tb = hb[vb[pos]], tc = hc[vc[pos]];
	for (unsigned i = 0; i < b[pos].size(); i++)
		if (b[pos][i] > 0) hb[b[pos][i]]++;
		else hb[-b[pos][i]]--;
	for (unsigned i = 0; i < c[pos].size(); i++)
		if (c[pos][i] > 0) hc[c[pos][i]]++;
		else hc[-c[pos][i]]--;
	for (unsigned i = 0; i < a[pos].size(); i++)
		if (a[pos][i] != fa) work(a[pos][i], pos);
	ans[pos] += hb[vb[pos]] - tb + hc[vc[pos]] - tc;
}
int main() {
	int n, m;
	read(n), read(m);
	for (int i = 1; i <= n - 1; i++) {
		int x, y;
		read(x), read(y);
		a[x].push_back(y);
		a[y].push_back(x);
	}
	dfs(1, 0);
	for (int i = 1; i <= n; i++) {
		read(t[i]);
		vb[i] = depth[i] + t[i];
		vc[i] = t[i] - depth[i] + n;
	}
	for (int i = 1; i <= m; i++) {
		int x, y, z;
		read(x), read(y);
		z = lca(x, y);
		int dx = depth[x] - depth[z];
		int dy = depth[y] - depth[z];
		if (t[z] == dx) ans[z]++;
		b[x].push_back(depth[x]);
		b[z].push_back(-depth[x]);
		c[y].push_back(dx + dy - depth[y] + n);
		c[z].push_back(-dx - dy + depth[y] - n);
	}
	work(1, 0);
	for (int i = 1; i <= n; i++)
		printf("%d\n", ans[i]);
	return 0;
}