zoukankan      html  css  js  c++  java
  • [洛谷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 }
  • 相关阅读:
    时域和频域
    Python实用笔记 (26)面向对象高级编程——定制类
    Python实用笔记 (25)面向对象高级编程——多重继承
    去重-pd.duplicated
    合并pd.merge
    拼接
    pandas读取txt、excel、csv
    pandas字符串操作
    常用数据编辑-相加对齐
    成员判断
  • 原文地址:https://www.cnblogs.com/cervusy/p/10001382.html
Copyright © 2011-2022 走看看