以下是AC代码。但是如果我把47行移到54行就RE,我已经裂开了。我在代码里注释了
这道题:点分治模板
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define NDEBUG
#include <assert.h>
using namespace std;
typedef vector<int> vi;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef unsigned int ui;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
#define endl '\n'
#define rd read()
#define pb push_back
#define mst(a, b) memset((a), (b), sizeof(a));
#define inf (10000000)
#define linf 0x3f3f3f3f3f3f3f3f
#define ls (u << 1)
#define rs (u << 1 | 1)
#define mod ((int)1e9+7)
#define maxn (int)(1e5+5)
int ans[inf];//它移到struct的上面一行定义就会RE???
int n, m, q[maxn];
int mxp[maxn], sz[maxn];
int sum, rt, tot;
int dis[maxn], rem[maxn];
int tmp[maxn];
int vis[maxn], judge[inf];
struct edge {
int u, v, w;
edge(int _u = 0, int _v = 0, int _w = 0) {u = _u, v = _v, w = _w;}
};
vector<edge> e[maxn];
void ins(int u, int v, int w) {e[u].push_back(edge(u, v, w));}
void inp() {
cin >> n >> m;
for(int i = 1; i < n; ++i) {
int u = rd, v = rd, w = rd;
ins(u, v, w), ins(v, u, w);
}
for(int i = 1; i <= m; ++i)
q[i] = rd;
}
void getrt(int u, int fa) {
sz[u] = 1;
mxp[u] = 0;//
for(ui i = 0; i < e[u].size(); ++i) {
int v = e[u][i].v;
if(v == fa || vis[v]) continue;
getrt(v, u);
sz[u] += sz[v];
mxp[u] = max(mxp[u], sz[v]);
}
mxp[u] = max(mxp[u], sum - sz[u]);
if(mxp[u] < mxp[rt]) rt = u;
}
void getdis(int u, int fa) {
rem[++rem[0]] = dis[u];
for(ui i = 0; i < e[u].size(); ++i) {
int v = e[u][i].v, w = e[u][i].w;
if(v == fa || vis[v]) continue;
dis[v] = dis[u] + w;
getdis(v, u);
}
}
void calc(int u) {
int p = 0;
for(ui i = 0; i < e[u].size(); ++i) {
int v = e[u][i].v, w = e[u][i].w;
if(vis[v]) continue;
rem[0] = 0, dis[v] = w, getdis(v, u);//
for(int j = rem[0]; j; --j)
for(int k = 1; k <= m; ++k)
if(q[k] >= rem[j])
ans[k] |= judge[q[k] - rem[j]];
for(int j = rem[0]; j; --j)
tmp[++p] = rem[j], judge[rem[j]] = true;
}
for(int i = 1; i <= p; ++i)
judge[tmp[i]] = false;
}
void solve(int u) {
vis[u] = judge[0] = true, calc(u);
for(ui i = 0; i < e[u].size(); ++i) {
int v = e[u][i].v;
if(vis[v]) continue;
sum = sz[v], mxp[rt = 0] = inf;//
getrt(v, 0), solve(rt);//
}
}
void outp() {
for(int i = 1; i <= m; ++i)
puts(ans[i] ? "AYE" : "NAY");
}
int main() {
#ifndef ONLINE_JUDGE
freopen("D:\\Chrome Downloadings\\input.txt", "r", stdin);
freopen("D:\\Chrome Downloadings\\output.txt", "w", stdout);
#endif
inp();
sum = mxp[rt] = n;
getrt(1, 0);
solve(rt);
outp();
return 0;
}