zoukankan      html  css  js  c++  java
  • 树链剖分

    洛谷 P3384 【模板】树链剖分

    错误记录:

    1.线段树(54行写成dat[num]=(dat[num]+x)%md;,缺少61行,缺少58行pushdown)

    2.113、127行缺少对于L>R的特判

    3.以前额外记了一个数组ou[i]表示i子树的出时间戳,然而可以直接用id[i]+sz[i]-1得到

    来看看树剖我还犯过哪些错吧:


    线段树空间没开够


    1.分清pos[a],arr[a]

    2.复制的时候没有将所有需要改的改掉

    3.链操作的最后一步没有a!=b或其他的判断语句,直接查询

    4.链操作不是dep[a]<dep[b],应为dep[top[a]]<dep[top[b]]这里是比较链顶点的深度,相当于比较两个点向上跳一次之后的深度,而不是自身的深度

    5.线段树建树时,注意线段树上点的下标是num而不是l,原数据一定要按a[arr[l]]取

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


    1.程序首行误与点分搞混,加了一句sz[0]=inf

    2.dfs1中没有sz[u]=1

      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[200100];
      9 LL f1[100100],ne;
     10 LL n,q,root,md;
     11 LL a[100100],sz[100100],ff[100100],hson[100100],tp[100100],dep[100100];
     12 LL arr[100100],id[100100];
     13 namespace SegT
     14 {
     15 #define mid ((l+r)>>1)
     16 #define lc (num<<1)
     17 #define rc (num<<1|1)
     18     LL dat[300100],addv[300100];
     19     LL L,R,x;
     20     void build(LL l,LL r,LL num)
     21     {
     22         if(l==r)
     23         {
     24             dat[num]=a[arr[l]]%md;
     25             return;
     26         }
     27         build(l,mid,lc);build(mid+1,r,rc);
     28         dat[num]=(dat[lc]+dat[rc])%md;
     29     }
     30     void pd(LL l,LL r,LL num)
     31     {
     32         if(addv[num])
     33         {
     34             dat[lc]=(dat[lc]+(mid-l+1)*addv[num])%md;
     35             dat[rc]=(dat[rc]+(r-mid)*addv[num])%md;
     36             addv[lc]=(addv[lc]+addv[num])%md;
     37             addv[rc]=(addv[rc]+addv[num])%md;
     38             addv[num]=0;
     39         }
     40     }
     41     LL query(LL l,LL r,LL num)
     42     {
     43         if(L<=l&&r<=R)    return dat[num];
     44         pd(l,r,num);
     45         LL ans=0;
     46         if(L<=mid)    ans=(ans+query(l,mid,lc))%md;
     47         if(mid<R)    ans=(ans+query(mid+1,r,rc))%md;
     48         return ans;
     49     }
     50     void addx(LL l,LL r,LL num)
     51     {
     52         if(L<=l&&r<=R)
     53         {
     54             dat[num]=(dat[num]+(r-l+1)*x)%md;
     55             addv[num]=(addv[num]+x)%md;
     56             return;
     57         }
     58         pd(l,r,num);
     59         if(L<=mid)    addx(l,mid,lc);
     60         if(mid<R)    addx(mid+1,r,rc);
     61         dat[num]=(dat[lc]+dat[rc])%md;
     62     }
     63 #undef mid
     64 #undef lc
     65 #undef rc
     66 }
     67 void dfs1(LL u)
     68 {
     69     sz[u]=1;
     70     for(LL k=f1[u];k;k=e[k].nxt)
     71         if(e[k].to!=ff[u])
     72         {
     73             ff[e[k].to]=u;
     74             dep[e[k].to]=dep[u]+1;
     75             dfs1(e[k].to);
     76             sz[u]+=sz[e[k].to];
     77             if(sz[hson[u]]<sz[e[k].to])    hson[u]=e[k].to;
     78         }
     79 }
     80 void dfs2(LL u)
     81 {
     82     arr[++arr[0]]=u;id[u]=arr[0];
     83     tp[u]=u==hson[ff[u]]?tp[ff[u]]:u;
     84     if(hson[u])    dfs2(hson[u]);
     85     for(LL k=f1[u];k;k=e[k].nxt)
     86         if(e[k].to!=ff[u]&&e[k].to!=hson[u])
     87         {
     88             dfs2(e[k].to);
     89         }
     90 }
     91 int main()
     92 {
     93     LL i,x,y,idx,ans;
     94     scanf("%lld%lld%lld%lld",&n,&q,&root,&md);
     95     for(i=1;i<=n;i++)    scanf("%lld",&a[i]);
     96     for(i=1;i<n;i++)
     97     {
     98         scanf("%lld%lld",&x,&y);
     99         e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;
    100         e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;
    101     }
    102     dfs1(root);dfs2(root);
    103     SegT::build(1,arr[0],1);
    104     while(q--)
    105     {
    106         scanf("%lld",&idx);
    107         if(idx==1)
    108         {
    109             scanf("%lld%lld%lld",&x,&y,&SegT::x);
    110             while(tp[x]!=tp[y])
    111             {
    112                 if(dep[tp[x]]<dep[tp[y]])    swap(x,y);
    113                 SegT::L=id[x],SegT::R=id[tp[x]];if(SegT::L>SegT::R)    swap(SegT::L,SegT::R);
    114                 SegT::addx(1,arr[0],1);
    115                 x=ff[tp[x]];
    116             }
    117             SegT::L=id[x],SegT::R=id[y];
    118             if(SegT::L>SegT::R)    swap(SegT::L,SegT::R);
    119             SegT::addx(1,arr[0],1);
    120         }
    121         else if(idx==2)
    122         {
    123             scanf("%lld%lld",&x,&y);ans=0;
    124             while(tp[x]!=tp[y])
    125             {
    126                 if(dep[tp[x]]<dep[tp[y]])    swap(x,y);
    127                 SegT::L=id[x],SegT::R=id[tp[x]];if(SegT::L>SegT::R)    swap(SegT::L,SegT::R);
    128                 ans=(ans+SegT::query(1,arr[0],1))%md;
    129                 x=ff[tp[x]];
    130             }
    131             SegT::L=id[x],SegT::R=id[y];
    132             if(SegT::L>SegT::R)    swap(SegT::L,SegT::R);
    133             ans=(ans+SegT::query(1,arr[0],1))%md;
    134             printf("%lld
    ",ans);
    135         }
    136         else if(idx==3)
    137         {
    138             scanf("%lld%lld",&x,&SegT::x);
    139             SegT::L=id[x],SegT::R=id[x]+sz[x]-1,SegT::addx(1,arr[0],1);
    140         }
    141         else if(idx==4)
    142         {
    143             scanf("%lld",&x);
    144             SegT::L=id[x],SegT::R=id[x]+sz[x]-1,ans=SegT::query(1,arr[0],1)%md;
    145             printf("%lld
    ",ans);
    146         }
    147     }
    148     return 0;
    149 }

    树剖lca

     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[1000100];
     9 LL f1[500100],ne;
    10 LL n,q,root,md;
    11 LL a[500100],sz[500100],ff[500100],hson[500100],tp[500100],dep[500100];
    12 LL arr[500100],id[500100];
    13 void dfs1(LL u)
    14 {
    15     sz[u]=1;
    16     for(LL k=f1[u];k;k=e[k].nxt)
    17         if(e[k].to!=ff[u])
    18         {
    19             ff[e[k].to]=u;
    20             dep[e[k].to]=dep[u]+1;
    21             dfs1(e[k].to);
    22             sz[u]+=sz[e[k].to];
    23             if(sz[hson[u]]<sz[e[k].to])    hson[u]=e[k].to;
    24         }
    25 }
    26 void dfs2(LL u)
    27 {
    28     arr[++arr[0]]=u;id[u]=arr[0];
    29     tp[u]=u==hson[ff[u]]?tp[ff[u]]:u;
    30     if(hson[u])    dfs2(hson[u]);
    31     for(LL k=f1[u];k;k=e[k].nxt)
    32         if(e[k].to!=ff[u]&&e[k].to!=hson[u])
    33         {
    34             dfs2(e[k].to);
    35         }
    36 }
    37 int main()
    38 {
    39     LL i,x,y;
    40     scanf("%lld%lld%lld",&n,&q,&root);
    41     for(i=1;i<n;i++)
    42     {
    43         scanf("%lld%lld",&x,&y);
    44         e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;
    45         e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;
    46     }
    47     dfs1(root);dfs2(root);
    48     while(q--)
    49     {
    50         scanf("%lld%lld",&x,&y);
    51         while(tp[x]!=tp[y])
    52         {
    53             if(dep[tp[x]]<dep[tp[y]])    swap(x,y);
    54             x=ff[tp[x]];
    55         }
    56         if(dep[x]<dep[y])    swap(x,y);
    57         printf("%lld
    ",y);
    58     }
    59     return 0;
    60 }
    View Code

    两组数据

    5 5 1 23333333
    5 7 3 4 3 
    5 1
    4 3
    1 4
    5 2
    2 4 2
    1 2 5 2
    2 4 5
    4 5
    3 3 1
    5 5 4 23333333
    7 9 4 9 2 
    2 4
    3 5
    1 3
    2 3
    2 2 5
    1 4 3 5
    1 1 5 6
    4 4
    4 5

    数据生成器

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    
    int fa[100100];
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    int main()
    {
        int t,i,z,idx;
        cin>>t;srand(t);
        int n=5,m=5,root=rand()%5+1,md=23333333;
        int x,y,fx,fy;
        printf("%d %d %d %d
    ",n,m,root,md);
        for(i=1;i<=n;i++)    fa[i]=i;
        for(i=1;i<=n;i++)    printf("%d ",rand()%10);
        puts("");
        for(i=1;i<n;i++)
        {
            do{
            x=rand()%n+1,y=rand()%n+1;
            fx=find(x);fy=find(y);
            }while(fx==fy);
            fa[fx]=fy;printf("%d %d
    ",x,y);
        }
        for(i=1;i<=m;i++)
        {
            x=rand()%n+1,y=rand()%n+1,z=rand()%10;
            idx=rand()%4+1;printf("%d ",idx);
            if(idx==1)
            {
                printf("%d %d %d
    ",x,y,z);
            }
            else if(idx==2)
            {
                printf("%d %d
    ",x,y);
            }
            else if(idx==3)
            {
                printf("%d %d
    ",x,z);
            }
            else if(idx==4)
            {
                printf("%d
    ",x);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    问题6-10
    7.19 1
    经济学人常见词汇清单
    英语广播原声听力100篇MP3及听力原文
    6.30.2018
    6.26
    6.26
    6.26
    6.25
    6.25
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8614329.html
Copyright © 2011-2022 走看看