【BZOJ4719】【NOIP2016】天天愛跑步
阿新 • • 發佈:2018-12-31
【題目連結】
【思路要點】
- 補檔部落格,無題解。
【程式碼】
#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; }