题解 P3806 【【模板】点分治1】(待填坑)

pantw

2018-01-22 00:03:36

Personal

借鉴了题解区的写法。 ```cpp #include <set> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 10010 #define maxm 20010 #define INF 0x3F3F3F3F using namespace std; inline int r() { char c = getchar(); int x = 0; while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') x = 10 * x + c - '0', c = getchar(); return x; } inline int max(int a, int b) { return a > b ? a : b; } int n, m, k[107]; int head[maxn], nxt[maxm], to[maxm], weight[maxm], ec; int que[maxn], tou, dis[maxn]; int siz[maxn], sum, root, rtson; bool vis[maxn], ans[maxn]; void add(int u, int v, int w) { nxt[++ec] = head[u]; head[u] = ec; weight[ec] = w; to[ec] = v; } void getroot(int x, int fa) { int son = 0; siz[x] = 1; for(int e = head[x]; e; e = nxt[e]) if(to[e] != fa && !vis[to[e]]) getroot(to[e], x), siz[x] += siz[to[e]], son = max(son, siz[to[e]]); if((son = max(son, sum - siz[x])) < rtson) root = x, rtson = son; } void dfs(int x, int fa) { que[tou++] = dis[x]; for(int e = head[x]; e; e = nxt[e]) if(to[e] != fa && !vis[to[e]]) dis[to[e]] = dis[x] + weight[e], dfs(to[e], x); } set<int> S; void query(int x) { for(int i = 1; i <= m; i++) if(!ans[i]) ans[i] = *S.lower_bound(k[i] - x) == k[i] - x; } void solve(int x) { S.clear(); vis[x] = true; S.insert(0); for(int e = head[x]; e; e = nxt[e]) { if(!vis[to[e]]) { tou = 0; dis[to[e]] = weight[e]; dfs(to[e], 0); for(int i = 0; i < tou; i++) query(que[i]); for(int i = 0; i < tou; i++) S.insert(que[i]); } } for(int e = head[x]; e; e = nxt[e]) { if(!vis[to[e]]) { rtson = sum = siz[to[e]]; getroot(to[e], 0); solve(to[e]); } } } int main() { n = r(); m = r(); for(int i = 1; i < n; i++) { int u, v, w; u = r(), v = r(), w = r(); add(u, v, w); add(v, u, w); } for(int i = 1; i <= m; i++) k[i] = r(); rtson = sum = n, getroot(1, 0), solve(root); for(int i = 1; i <= m; i++) puts(ans[i] ? "AYE" : "NAY"); return 0; } ```