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

    最近好像掉进什么奇怪的数据结构坑里去了。。。。

    先放个板子,讲解和例题到时候在补上

    # include<cstring>
    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<cstdio>
    # include<algorithm>
    
    using std::swap;
    const int mn = 200005;
    
    struct edge{int to,next;};
    edge e[mn*2];
    int head[mn],edge_max;
    int n,m,r,mod;
    int val[mn],w[mn];
    int deep[mn],siz[mn],fa[mn];
    int id[mn],bl[mn],tot;
    struct tree{int l,r,sum,lazy;};
    tree  tr[mn*4];
    void add(int x,int y)
    {
        e[++edge_max].to=y;
        e[edge_max].next=head[x];
        head[x]=edge_max;
    }
    void dfs1(int x)
    {
        siz[x]=1;
        for(int i=head[x];i;i=e[i].next)
        {
            int u=e[i].to;
            if(u!=fa[x])
            {
                deep[u]=deep[x]+1;
                fa[u]=x;
                dfs1(u);
                siz[x]+=siz[u];
            }
        }
    }
    void dfs2(int x,int chain)
    {
        int k=0;
        id[x]=++tot;
        w[tot]=val[x];
        bl[x]=chain;
        for(int i=head[x];i;i=e[i].next)
        {
            int u=e[i].to;
            if(deep[u]>deep[x] && siz[u]>siz[k])
                k=u;
        }
        if(!k)
            return ;
        dfs2(k,chain);
        for(int i=head[x];i;i=e[i].next)
        {
            int u=e[i].to;
            if(deep[u]>deep[x] && u!=k)
                dfs2(u,u);
        }
    }
    void build(int l,int r,int cur)
    {
        tr[cur].l=l,tr[cur].r=r;
        if(l==r)
        {
            tr[cur].sum=(w[l])%mod;
            return ;
        }
        int mid=l+r>>1;
        build(l,mid,cur<<1);
        build(mid+1,r,cur<<1|1);
        tr[cur].sum=(tr[cur<<1].sum+tr[cur<<1|1].sum)%mod;
    }
    void pushdown(int cur)
    {
        if(tr[cur].lazy!=0)
        {
            tr[cur<<1].sum=(tr[cur<<1].sum+(tr[cur<<1].r-tr[cur<<1].l+1)*tr[cur].lazy)%mod;
            tr[cur<<1|1].sum=(tr[cur<<1|1].sum+(tr[cur<<1|1].r-tr[cur<<1|1].l+1)*tr[cur].lazy)%mod;
            tr[cur<<1].lazy=(tr[cur<<1].lazy+tr[cur].lazy)%mod;
            tr[cur<<1|1].lazy=(tr[cur<<1|1].lazy+tr[cur].lazy)%mod;
            tr[cur].lazy=0;
        }
        return ;
    }
    void update(int cur,int L,int R,int x)
    {
        if(tr[cur].l>R || tr[cur].r<L)
            return ;
        if(tr[cur].l>=L && tr[cur].r<=R)
        {
            tr[cur].sum=((tr[cur].r-tr[cur].l+1)*x+tr[cur].sum)%mod;
            tr[cur].lazy=(tr[cur].lazy+x)%mod;
            return ;
        }
        pushdown(cur);
        update(cur<<1,L,R,x);
        update(cur<<1|1,L,R,x);
        tr[cur].sum=(tr[cur<<1].sum+tr[cur<<1|1].sum)%mod;
    }
    void treeadd(int x,int y,int z)
    {
        while(bl[x]!=bl[y])
        {
            if(deep[bl[x]]<deep[bl[y]])
                swap(x,y);
            update(1,id[bl[x]],id[x],z);
            x=fa[bl[x]];
        }
        if(deep[x]>deep[y])
           swap(x,y);
        update(1,id[x],id[y],z);
    }
    int query(int cur,int L,int R)
    {
        if(tr[cur].l>=L && tr[cur].r<=R)
            return tr[cur].sum;
        if(tr[cur].l>R || tr[cur].r<L)
            return 0;
        pushdown(cur);
        int ans=0;
        ans=query(cur<<1,L,R);
        ans+=query(cur<<1|1,L,R);
        tr[cur].sum=(tr[cur<<1].sum+tr[cur<<1|1].sum)%mod;
        ans=ans%mod;
        return ans;
    }
    void treesum(int x,int y)
    {
        int ret=0;
        while(bl[x]!=bl[y])
        {
            if(deep[bl[x]]<deep[bl[y]])
                swap(x,y);
            ret=(ret+query(1,id[bl[x]],id[x]))%mod;
            x=fa[bl[x]];
        }
        if(deep[x]>deep[y])
            swap(x,y);
        ret=(ret+query(1,id[x],id[y]))%mod;
        printf("%d
    ",ret);
    }
    int main()
    {
       int x,y,opt,z;
       scanf("%d%d%d%d",&n,&m,&r,&mod);
       for(int i=1;i<=n;i++)
         scanf("%d",&val[i]);
       for(int i=1;i<n;i++)
       {
           scanf("%d%d",&x,&y);
           add(x,y),add(y,x);
       }
       deep[r]=1;
       dfs1(r);
       dfs2(r,r);
       build(1,n,1);
       for(int i=1;i<=m;i++)
       {
          scanf("%d%d",&opt,&x);
          if(opt==1)
          {
              scanf("%d%d",&y,&z);
              treeadd(x,y,z%mod);
          }
          else if(opt==2)
          {
              scanf("%d",&y);
              treesum(x,y);
          }
          else if(opt==3)
          {
              scanf("%d",&y);
              update(1,id[x],id[x]+siz[x]-1,y%mod);
          }
          else {
            printf("%d
    ",query(1,id[x],id[x]+siz[x]-1));
          }
       }
       return 0;
    }
  • 相关阅读:
    A Node Influence Based Label Propagation Algorithm for Community detection in networks 文章算法实现的疑问
    Fast Newman-FN算法以及模块度定义介绍
    Label Propagation Algorithm LPA 标签传播算法解析及matlab代码实现
    设计一个smartnic
    Intel GEN11 GPU
    Intel GEN9 GPU
    Shared Virtual Memory (SVM) Functions
    connect via ssh to virtualbox guest vm without knowing ip address
    smartnic
    技术精品翻译
  • 原文地址:https://www.cnblogs.com/logeadd/p/8918672.html
Copyright © 2011-2022 走看看