[洛谷P3806] [模板] 点分治1
这个点分治都不用减掉子树里的了,直接搞就行了。
注意第63行 if(qu[k]>=buf[j]) 不能不写,也不能写成>。
因为这个WA了半天......
如果memset清空ex数组显然是会T的,所以开一个bef用来记录需要清空哪个地方。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n,m; 7 int hd[10005],to[20005],nx[20005],len[20005],ec; 8 int qu[105],ans[105]; 9 10 void edge(int af,int at,int el) 11 { 12 to[++ec]=at; 13 len[ec]=el; 14 nx[ec]=hd[af]; 15 hd[af]=ec; 16 } 17 18 int rt,tot; 19 int sz[10005],mx[10005]; 20 int del[10005]; 21 22 void weigh(int p,int fa) 23 { 24 sz[p]=1;mx[p]=0; 25 for(int i=hd[p];i;i=nx[i]) 26 { 27 int t=to[i]; 28 if(t==fa||del[t])continue; 29 weigh(t,p); 30 sz[p]+=sz[t]; 31 mx[p]=max(mx[p],sz[t]); 32 } 33 mx[p]=max(mx[p],tot-sz[p]); 34 if(mx[p]<mx[rt])rt=p; 35 } 36 37 int dis[10005]; 38 int buf[10005],tp,ex[10000005],bef[10005],btp; 39 40 void dfs(int p,int fa) 41 { 42 buf[++tp]=dis[p]; 43 for(int i=hd[p];i;i=nx[i]) 44 { 45 int t=to[i]; 46 if(fa==t||del[t])continue; 47 dis[t]=dis[p]+len[i]; 48 dfs(t,p); 49 } 50 } 51 52 void count(int p) 53 { 54 btp=0; 55 for(int i=hd[p];i;i=nx[i]) 56 { 57 int t=to[i]; 58 if(del[t])continue; 59 tp=0;dis[t]=len[i]; 60 dfs(t,p); 61 for(int j=1;j<=tp;j++) 62 for(int k=1;k<=m;k++) 63 if(qu[k]>=buf[j]) 64 ans[k]|=ex[qu[k]-buf[j]]; 65 for(int j=1;j<=tp;j++) 66 bef[++btp]=buf[j],ex[buf[j]]=1; 67 } 68 for(int i=1;i<=btp;i++)ex[bef[i]]=0; 69 } 70 71 void conquer(int p) 72 { 73 del[p]=ex[0]=1; 74 count(p); 75 for(int i=hd[p];i;i=nx[i]) 76 { 77 int t=to[i]; 78 if(del[t])continue; 79 rt=0;tot=sz[t]; 80 weigh(t,0); 81 conquer(rt); 82 } 83 } 84 85 int main() 86 { 87 scanf("%d%d",&n,&m); 88 for(int i=1;i<n;i++) 89 { 90 int ff,tt,vv; 91 scanf("%d%d%d",&ff,&tt,&vv); 92 edge(ff,tt,vv); 93 edge(tt,ff,vv); 94 } 95 for(int i=1;i<=m;i++)scanf("%d",&qu[i]); 96 mx[0]=tot=n; 97 weigh(1,0); 98 conquer(rt); 99 for(int i=1;i<=m;printf("\n"),i++) 100 printf(ans[i]?"AYE":"NAY"); 101 return 0; 102 }