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

    树剖要多打

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<map>
    #define inf 2000000000
    #define min(x,y) ((x)<(y)?(x):(y))
    #define max(x,y) ((x)>(y)?(x):(y))
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int N=100000;
    int fa[N+10],dep[N+10],sz[N+10],son[N+10],top[N+10],seg[N+10],rev[N+10];
    int n,m,root;
    ll p,num[N+10],add[4*N+10],sum[4*N+10];
    int tot=1,head[N+10];
    struct EDGE
    {
        int to,nxt;
    }edge[2*N+10];
    void add_edge(int u,int v)
    {
        edge[++tot].to=v;
        edge[tot].nxt=head[u];
        head[u]=tot;
    }
    void dfs1(int x,int f)
    {
        sz[x]=1;
        fa[x]=f;
        dep[x]=dep[f]+1;
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int y=edge[i].to;
            if(y!=f)
            {
                dfs1(y,x);
                sz[x]+=sz[y];
                if(sz[y]>sz[son[x]]) son[x]=y;
            }
        }
    }
    void dfs2(int x,int t)
    {
        top[x]=t;
        seg[x]=++seg[0];
        rev[seg[0]]=x;
        if(!son[x]) return;
        dfs2(son[x],t);
        for(int i=head[x];i;i=edge[i].nxt)
        {
            int y=edge[i].to;
            if(y==fa[x]||y==son[x]) continue;
            dfs2(y,y);
        }
    }
    void build(int k,int l,int r)
    {
        if(l==r)
        {
            sum[k]=num[rev[l]];
            return;
        }
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        sum[k]=(sum[k<<1]+sum[k<<1|1])%p;
    }
    void spread(int k,int l,int r)
    {
        if(add[k])
        {
            int mid=(l+r)>>1;
            sum[k<<1]=(sum[k<<1]+add[k]*(mid-l+1))%p;
            add[k<<1]=(add[k<<1]+add[k])%p;
            sum[k<<1|1]=(sum[k<<1|1]+add[k]*(r-mid))%p;
            add[k<<1|1]=(add[k<<1|1]+add[k])%p;
            add[k]=0;
        }
    }
    void ask_add(int k,int l,int r,int ql,int qr,ll d)
    {
        if(ql<=l&&r<=qr)
        {
            add[k]=(add[k]+d)%p;
            sum[k]=(sum[k]+d*(r-l+1))%p;
            return;
        }
        spread(k,l,r);
        int mid=(l+r)>>1;
        if(ql<=mid) ask_add(k<<1,l,mid,ql,qr,d);
        if(qr>=mid+1) ask_add(k<<1|1,mid+1,r,ql,qr,d);
        sum[k]=(sum[k<<1]+sum[k<<1|1])%p;
    }
    ll ask_sum(int k,int l,int r,int ql,int qr)
    {
        if(ql<=l&&r<=qr)
        {
            return sum[k];
        }
        spread(k,l,r);
        int mid=(l+r)>>1;
        ll val=0;
        if(ql<=mid) val=(val+ask_sum(k<<1,l,mid,ql,qr))%p;
        if(qr>=mid+1) val=(val+ask_sum(k<<1|1,mid+1,r,ql,qr))%p;
        return val;
    }
    ll ask_path(int x,int y,ll d)
    {
        ll val=0;
        int fx=top[x],fy=top[y];
        while(fx!=fy)
        {
            if(dep[fx]>dep[fy]) swap(x,y),swap(fx,fy);
            if(d==0) val=(val+ask_sum(1,1,seg[0],seg[fy],seg[y]))%p;
            else ask_add(1,1,seg[0],seg[fy],seg[y],d);
            y=fa[fy];fy=top[y];
        }
        if(dep[x]>dep[y]) swap(x,y);
        if(d==0)
        {
            val=(val+ask_sum(1,1,seg[0],seg[x],seg[y]))%p;
            return val;
        }
        else
        {
            ask_add(1,1,seg[0],seg[x],seg[y],d);
            return 0;
        }
    }
    int main()
    {
        scanf("%d%d%d%lld",&n,&m,&root,&p);
        rep(i,1,n)
        {
            scanf("%lld",&num[i]);
            num[i]%=p;
        }
        rep(i,1,n-1)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add_edge(x,y),add_edge(y,x);
        }
        dfs1(root,0);
        dfs2(root,root);
        build(1,1,seg[0]);
        rep(i,1,m)
        {
            int t;
            scanf("%d",&t);
            if(t==1)
            {
                int x,y;ll z;
                scanf("%d%d%lld",&x,&y,&z);
                if(z==0) continue;
                ask_path(x,y,z%p);
            }
            if(t==2)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                printf("%lld
    ",ask_path(x,y,0));
            }
            if(t==3)
            {
                int x;ll z;
                scanf("%d%lld",&x,&z);
                ask_add(1,1,seg[0],seg[x],seg[x]+sz[x]-1,z%p);
            }
            if(t==4)
            {
                int x;
                scanf("%d",&x);
                printf("%lld
    ",ask_sum(1,1,seg[0],seg[x],seg[x]+sz[x]-1));
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    The Mac Application Environment 不及格的程序员
    Xcode Plugin: Change Code In Running App Without Restart 不及格的程序员
    The property delegate of CALayer cause Crash. 不及格的程序员
    nil localizedTitle in SKProduct 不及格的程序员
    InApp Purchase 不及格的程序员
    Safari Web Content Guide 不及格的程序员
    在Mac OS X Lion 安装 XCode 3.2 不及格的程序员
    illustrate ARC with graphs 不及格的程序员
    Viewing iPhoneOptimized PNGs 不及格的程序员
    What is the dSYM? 不及格的程序员
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/11151732.html
Copyright © 2011-2022 走看看