• bzoj 1036: [ZJOI2008]树的统计Count


    树剖板子

    然而不停WA....

    注意:

    1.分清pos[a],arr[a];曾经116行pos[a]写成a,WA

    2.134行曾经复制的时候没改,成了qmax(..)

    3.126,137行这里没有a!=b或其他的判断语句,直接查询

    4.133行不是dep[a]<dep[b],这里是比较链顶点的深度,相当于比较两个点向上跳一次之后的深度,而不是自身的深度

    5.46行不要写成maxn[l],a[num],a[l],...注意线段树上点的下标是num,原数据一定要按a[arr[l]]取

    6.各个取最大值的函数初始值要为-inf,而各个取和的函数初始值要为0

      1 #include<cstdio>
      2 #include<algorithm>
      3 using namespace std;
      4 typedef long long LL;
      5 struct E
      6 {
      7     LL to,nxt;
      8 }e[60100];
      9 LL f1[30100],ne;
     10 LL hson[30100],f[30100],sz[30100],arr[30100],pos[30100],top[30100],dep[30100];
     11 LL aa[30100];
     12 void dfs1(LL u,LL fa)
     13 {
     14     sz[u]=1;
     15     for(LL k=f1[u];k;k=e[k].nxt)
     16         if(e[k].to!=fa)
     17         {
     18             dep[e[k].to]=dep[u]+1;
     19             dfs1(e[k].to,u);
     20             sz[u]+=sz[e[k].to];
     21             if(sz[hson[u]]<sz[e[k].to])    hson[u]=e[k].to;
     22         }
     23 }
     24 void dfs2(LL u,LL fa)
     25 {
     26     arr[++arr[0]]=u;pos[u]=arr[0];
     27     f[u]=fa;
     28     if(u==hson[fa])    top[u]=top[fa];
     29     else    top[u]=u;
     30     if(hson[u])    dfs2(hson[u],u);
     31     for(LL k=f1[u];k;k=e[k].nxt)
     32         if(e[k].to!=fa&&e[k].to!=hson[u])
     33         {
     34             dfs2(e[k].to,u);
     35         }
     36 }
     37 LL n,q;
     38 namespace SegT
     39 {
     40 #define mid (l+((r-l)>>1))
     41 #define lc (num<<1)
     42 #define rc (num<<1|1)
     43     LL maxn[120100],sum[120100];
     44     void build(LL l,LL r,LL num)
     45     {
     46         if(l==r)    {maxn[num]=sum[num]=aa[arr[l]];return;}
     47         build(l,mid,lc);build(mid+1,r,rc);
     48         maxn[num]=max(maxn[lc],maxn[rc]);
     49         sum[num]=sum[lc]+sum[rc];
     50     }
     51     LL L,R,x;
     52     void _update(LL l,LL r,LL num)
     53     {
     54         if(l==r)    {maxn[num]=sum[num]=x;return;}
     55         if(L<=mid)    _update(l,mid,lc);
     56         else    _update(mid+1,r,rc);
     57         maxn[num]=max(maxn[lc],maxn[rc]);
     58         sum[num]=sum[lc]+sum[rc];
     59     }
     60     LL _qmax(LL l,LL r,LL num)
     61     {
     62         if(L<=l&&r<=R)    return maxn[num];
     63         LL ans=-0x3f3f3f3f;
     64         if(L<=mid)    ans=max(ans,_qmax(l,mid,lc));
     65         if(mid<R)    ans=max(ans,_qmax(mid+1,r,rc));
     66         return ans;
     67     }
     68     LL _qsum(LL l,LL r,LL num)
     69     {
     70         if(L<=l&&r<=R)    return sum[num];
     71         LL ans=0;
     72         if(L<=mid)    ans+=_qsum(l,mid,lc);
     73         if(mid<R)    ans+=_qsum(mid+1,r,rc);
     74         return ans;
     75     }
     76     void update(LL a,LL b)
     77     {
     78         L=a;x=b;_update(1,n,1);
     79     }
     80     LL qmax(LL l,LL r)
     81     {
     82         L=l;R=r;if(L>R)    swap(L,R);
     83         return _qmax(1,n,1);
     84     }
     85     LL qsum(LL l,LL r)
     86     {
     87         L=l;R=r;if(L>R)    swap(L,R);
     88         return _qsum(1,n,1);
     89     }
     90 #undef mid
     91 #undef lc
     92 #undef rc
     93 }
     94 using SegT::qmax;
     95 using SegT::qsum;
     96 int main()
     97 {
     98     LL i,a,b,ans;char tmp[10];
     99     scanf("%lld",&n);
    100     for(i=1;i<n;i++)
    101     {
    102         scanf("%lld%lld",&a,&b);
    103         e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
    104         e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
    105     }
    106     for(i=1;i<=n;i++)    scanf("%lld",&aa[i]);
    107     dfs1(1,0);dfs2(1,0);
    108     SegT::build(1,n,1);
    109     scanf("%lld",&q);
    110     while(q--)
    111     {
    112         scanf("%s%lld%lld",tmp,&a,&b);
    113         switch(tmp[1])
    114         {
    115         case 'H':
    116             SegT::update(pos[a],b);
    117             break;
    118         case 'M':
    119             ans=-0x3f3f3f3f;
    120             while(top[a]!=top[b])
    121             {
    122                 if(dep[top[a]]<dep[top[b]])    swap(a,b);
    123                 ans=max(ans,qmax(pos[a],pos[top[a]]));
    124                 a=f[top[a]];
    125             }
    126             ans=max(ans,qmax(pos[a],pos[b]));
    127             printf("%lld
    ",ans);
    128             break;
    129         case 'S':
    130             ans=0;
    131             while(top[a]!=top[b])
    132             {
    133                 if(dep[top[a]]<dep[top[b]])    swap(a,b);//不是dep[a]<dep[b]
    134                 ans+=qsum(pos[a],pos[top[a]]);//曾经不小心复制错,成了qmax(...)
    135                 a=f[top[a]];
    136             }
    137             ans+=qsum(pos[a],pos[b]);//没有if(a!=b)
    138             printf("%lld
    ",ans);
    139             break;
    140         }
    141     }
    142     return 0;
    143 }
  • 相关阅读:
    Python Day23
    Python Day22
    Python Day21
    Python Day20
    Python Day19
    Python Day18
    Python Day17
    Python Day15
    Appium python unittest pageobject如何实现加载多个case
    Appium python Uiautomator2 多进程问题
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8885656.html
Copyright © 2020-2023  润新知