# 「点分治」学习笔记

Code

/*DennyQi 2019*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 10010;
int x(0),w(1); char c = getchar();
while(c^'-' && (c<'0' || c>'9')) c = getchar();
if(c=='-') w = -1, c = getchar();
while(c>='0' && c<='9') x = (x<<3)+(x<<1)+c-'0', c = getchar();
return x*w;
}
int n,m,x,y,z,S,rt,cnt,test[N],vis[N],sz[N],maxp[N],judge[10000010],rem[N],q[N],Q[N];
inline void add(int u, int v, int w){
to[++cnte] = v;
cost[cnte] = w;
}
void getrt(int u, int Fa){
sz[u] = 1;
maxp[u] = 0;
for(int i = head[u]; i; i = nxt[i]){
if(to[i] == Fa) continue;
if(vis[to[i]]) continue;
getrt(to[i],u);
sz[u] += sz[to[i]];
maxp[u] = max(maxp[u],sz[to[i]]);
}
maxp[u] = max(maxp[u],S-sz[u]);
if(maxp[u] < maxp[rt]) rt = u;
}
void getdis(int u, int Fa, int d){
rem[++cnt] = d;
for(int i = head[u]; i; i = nxt[i]){
if(to[i] == Fa) continue;
if(vis[to[i]]) continue;
getdis(to[i],u,d+cost[i]);
}
}
inline void calc(int u){
int p = 0;
for(int i = head[u]; i; i = nxt[i]){
if(vis[to[i]]) continue;
cnt = 0;
getdis(to[i],u,cost[i]);
for(int j = 1; j <= cnt; ++j){
for(int k = 1; k <= m; ++k){
if(Q[k] >= rem[j]){
test[k] |= judge[Q[k]-rem[j]];
}
}
}
for(int j = 1; j <= cnt; ++j){
q[++p] = rem[j];
judge[rem[j]] = 1;
}
}
for(int i = 1; i <= p; ++i) judge[q[i]] = 0;
}
void solve(int u){
vis[u] = 1;
judge[0] = 1;
calc(u);
for(int i = head[u]; i; i = nxt[i]){
if(vis[to[i]]) continue;
S = sz[to[i]];
maxp[rt = 0] = 0x3f3f3f3f;
getrt(to[i],-1);
solve(rt);
}
}
int main(){
// freopen("file.in","r",stdin);
for(int i = 1; i < n; ++i){
}
for(int i = 1; i <= m; ++i) Q[i] = read();
S = n;
maxp[rt] = 0x3f3f3f3f;
getrt(1,-1);
solve(rt);
for(int i = 1; i <= m; ++i){
if(test[i]) printf("AYE\n"); else printf("NAY\n");
}
return 0;
}

posted @ 2019-07-02 08:41  DennyQi  阅读(258)  评论(0编辑  收藏  举报