zoukankan      html  css  js  c++  java
  • 傻逼调了一天树剖

    啊,,调了很久就是了。

    跳链的时候跳的是top的深度大的那个,不是本身深度大的。

    我是傻逼。

    洛谷树剖模板。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=100010;
    typedef long long ll;
    inline ll read(){
        ll f=1,r=0,c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){r=r*10+c-'0';c=getchar();}
        return r*f;
    }
    struct Edge{
        int to,nxt;
    }e[N*2];
    int head[N],cnt=1;ll P;
    void add(int u,int v){
        e[cnt]=(Edge){v,head[u]};
        head[u]=cnt++;
        e[cnt]=(Edge){u,head[v]};
        head[v]=cnt++;
    }
    int siz[N],dep[N],dad[N],son[N];
    void dfs1(int u,int fa){
        siz[u]=1;dad[u]=fa;
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].to;
            if(v==fa)continue;
            dep[v]=dep[u]+1;dfs1(v,u);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]])
            son[u]=v;
        }
    }
    int pos[N],top[N],dfn;
    void dfs2(int u,int anc){
        top[u]=anc;pos[u]=++dfn;
        if(!son[u])return;
        dfs2(son[u],anc);
        for(int i=head[u];i;i=e[i].nxt)
        if(e[i].to^dad[u]&&e[i].to^son[u])
        dfs2(e[i].to,e[i].to);
    }
    #define ls o<<1
    #define rs (o<<1)|1
    #define L T[o].l
    #define R T[o].r
    #define M L+R>>1
    struct Node{
        ll l,r,add,sum;
    }T[N*4];
    ll a[N],b[N];
    void pushdown(int o){
        (T[ls].add+=T[o].add)%=P;
        (T[rs].add+=T[o].add)%=P;
        (T[ls].sum+=(T[ls].r-T[ls].l+1)*T[o].add)%=P;
        (T[rs].sum+=(T[rs].r-T[rs].l+1)*T[o].add)%=P;
        T[o].add=0;
    }
    void pullup(int o){
        (T[o].sum=T[ls].sum+T[rs].sum)%=P;
    }
    void build(int o,int l,int r){
        if(l==r){
            T[o]=(Node){l,r,0,a[l]};
            return;
        }
        T[o]=(Node){l,r,0,0};
        build(ls,l,l+r>>1);
        build(rs,(l+r>>1)+1,r);
        pullup(o);
    }
    ll val,ans,ql,qr;
    void upd(int o){
        if(ql<=L&&R<=qr){
            (T[o].add+=val)%=P;
            (T[o].sum+=(R-L+1)*val)%=P;
            return;
        }
        pushdown(o);
        if(ql<=M)upd(ls);
        if(qr>M) upd(rs);
        pullup(o);
    }
    void qsum(int o){
        if(ql<=L&&R<=qr){
            (ans+=T[o].sum)%=P;
            return;
        }
        pushdown(o);
        if(ql<=M)qsum(ls);
        if(qr>M) qsum(rs);
    }
    void modify(int u,int v,ll t){
        val=t;
        while(top[u]^top[v]){
            if(dep[top[u]]<dep[top[v]])swap(u,v);
            ql=pos[top[u]],qr=pos[u];upd(1);
            u=dad[top[u]];
        }
        if(pos[u]>pos[v])swap(u,v);
        ql=pos[u],qr=pos[v];upd(1);
    }
    void query(int u,int v){
        ans=0;
        while(top[u]^top[v]){
            if(dep[top[u]]<dep[top[v]])swap(u,v);
            ql=pos[top[u]],qr=pos[u];qsum(1);
            u=dad[top[u]];
        }
        if(pos[u]>pos[v])swap(u,v);
        ql=pos[u],qr=pos[v];qsum(1);
        printf("%lld
    ",ans%P);
    }
    int n,m,S;
    void init(){
        n=read(),m=read(),S=read(),P=read();
        for(int i=1;i<=n;i++)b[i]=read();
        for(int i=1;i<n;i++)
        add(read(),read());
        dfs1(S,0);dfs2(S,S);
        for(int i=1;i<=n;i++)
        a[pos[i]]=b[i];
        build(1,1,n);
    }
    void solve(){
        while(m--){
            int opt=read();
            if(opt==1){
                int u=read(),v=read();ll t=read();
                modify(u,v,t);
            }
            else if(opt==2){
                int u=read(),v=read();
                query(u,v);
            }
            else if(opt==3){
                int u=read();
                ql=pos[u],qr=ql+siz[u]-1;
                val=read();upd(1);
            }
            else{
                int u=read();
                ans=0;
                ql=pos[u],qr=ql+siz[u]-1;
                qsum(1);
                printf("%lld
    ",ans%P);
            }
        }
    }
    int main(){
        init();
        solve();
    }
    View Code

    感觉150行,3KB左右,字数算不多了,打了几遍也基本记下来了。


    upd

    又手写了三道,板子没问题了具体问题能不能会做呢?那得问线段树了。。。

  • 相关阅读:
    团队冲刺2---个人工作总结一(5.25)
    第十二周学习进度
    课堂作业——找水王
    个人冲刺07
    第十五周学习进度情况
    构建之法阅读笔记06
    构建之法阅读笔记05
    第十四周学习进度情况
    个人冲刺06
    个人冲刺05
  • 原文地址:https://www.cnblogs.com/orzzz/p/7764539.html
Copyright © 2011-2022 走看看