[洛谷P3806] [模板] 点分治1

洛谷 P3806 传送门

这个点分治都不用减掉子树里的了,直接搞就行了。

注意第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("
"),i++)
100         printf(ans[i]?"AYE":"NAY");
101     return 0;
102 }
原文地址:https://www.cnblogs.com/cervusy/p/10001382.html