Problem
求是否存在权值和等于 K K K 的路径。
Solution
点分治啊
记录路径和为
x
x
x 的路径的个数
容斥一下
Code
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 10010
#define K 10000000
#define inf 0x3f3f3f3f
int n,m,num=0,sumroot=0,root=0,tot=0,h[N],sz[N],son[N],vis[N],d[N],q[N],cnt[K+1];
struct node{int to,z,next;}mp[N<<1];
inline void insert(int x,int y,int z){
mp[++num].to=y;mp[num].z=z;mp[num].next=h[x];h[x]=num;
mp[++num].to=x;mp[num].z=z;mp[num].next=h[y];h[y]=num;
}
void getroot(int x,int fa){
sz[x]=1;son[x]=0;
for(int i=h[x];i;i=mp[i].next){
int y=mp[i].to;if(y==fa || vis[y]) continue;
getroot(y,x);sz[x]+=sz[y];son[x]=max(son[x],sz[y]);
}son[x]=max(son[x],sumroot-sz[x]);
if(son[x]<son[root]) root=x;
}
void dist(int x,int fa){
q[++tot]=d[x];
for(int i=h[x];i;i=mp[i].next){
int y=mp[i].to;if(y==fa || vis[y]) continue;
d[y]=d[x]+mp[i].z;dist(y,x);
}
}
void calc(int x,int val,int op){
tot=0;d[x]=val;dist(x,0);
for(int i=1;i<=tot;i++)
for(int j=1;j<=tot;j++)
if(op && q[i]+q[j]<=K) ++cnt[q[i]+q[j]];
else if(!op && q[i]+q[j]<=K) --cnt[q[i]+q[j]];
}
void solve(int x){
calc(x,0,1);vis[x]=1;
for(int i=h[x];i;i=mp[i].next){
int y=mp[i].to;if(vis[y]) continue;
calc(y,mp[i].z,0);
sumroot=sz[y];root=0;getroot(y,0);solve(root);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
insert(x,y,z);
}
son[0]=inf;sumroot=n;getroot(1,0);
solve(root);
for(int i=1;i<=m;i++){
int x;scanf("%d",&x);
if(cnt[x]) puts("AYE");
else puts("NAY");
}
return 0;
}