把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

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");
}
posted @ 2021-05-16 12:17  275307894a  阅读(32)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end