luogu P3806 【模板】点分治1
题面传送门
发现以前自己写的像那个一样。
首先两次dfs找重心是显然的。这个可以保证分治复杂度。
然后就可以开个桶直接算即可。
时间复杂度\(O(nmlogn)\)
code:
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<algorithm>
#include<bitset>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define l(x) x<<1
#define r(x) x<<1|1
#define re register
#define ll long long
#define db double
#define W 10000000
#define N 10000
#define eps (1e-6)
#define mod 1000000007
using namespace std;
int n,m,k[N+5],ans[N+5],x,y,z,f[W+5],dp[N+5],siz[N+5],pus,len,d[N+5],maxn,fl[N+5];
struct yyy{int to,w,z;};
struct ljb{
int head,h[N+5];yyy f[N+5<<1];
I void add(int x,int y,int z){f[++head]=(yyy){y,z,h[x]};h[x]=head;}
}s;
I void dfs1(int x,int last){
yyy tmp;siz[x]=1;dp[x]=0;
for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^last&&fl[tmp.to]&&(dfs1(tmp.to,x),dp[x]=max(siz[tmp.to],dp[x]),siz[x]+=siz[tmp.to]);
}
I void dfs2(int x,int last){
yyy tmp;dp[x]=max(dp[x],len-siz[x]);dp[x]<dp[pus]&&(pus=x);
for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^last&&fl[tmp.to]&&(dfs2(tmp.to,x),0);
}
I void dfs3(int x,int last){
yyy tmp;for(int i=1;i<=m;i++) if(d[x]<=k[i]&&f[k[i]-d[x]])ans[i]|=(d[x]<=k[i]&&f[k[i]-d[x]]);
for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^last&&fl[tmp.to]&&(d[tmp.to]=d[x]+tmp.w,dfs3(tmp.to,x),0);
}
I void dfs4(int x,int w,int last){
yyy tmp;d[x]<=maxn&&(f[d[x]]+=w);
for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^last&&fl[tmp.to]&&(dfs4(tmp.to,w,x),0);
}
I void dfs(int x){
dfs1(x,0); pus=x;len=siz[x];dfs2(x,0);yyy tmp;d[x=pus]=0;f[0]=1;
for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],fl[tmp.to]&&(d[tmp.to]=tmp.w,dfs3(tmp.to,x),dfs4(tmp.to,1,x),0);
dfs4(x,-1,0);fl[x]=0;for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],fl[tmp.to]&&(dfs(tmp.to),0);
}
int main(){
freopen("1.in","r",stdin);freopen("1.out","w",stdout);
re int i;scanf("%d%d",&n,&m);for(i=1;i<n;i++) scanf("%d%d%d",&x,&y,&z),s.add(x,y,z),s.add(y,x,z);
for(i=1;i<=m;i++) scanf("%d",&k[i]) ,maxn=max(maxn,k[i]);for(i=1;i<=n;i++) fl[i]=1;dfs(1);
for(i=1;i<=m;i++) printf("%s\n",ans[i]?"AYE":"NAY");
}