• 【洛谷P1501】【国家集训队】Tree(LCT)


    传送门

    就和线段树维护区间加、乘标记一样
    板子题

    注意虽然模数很小但仍然会爆intint

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define int unsigned int
    inline int read(){
        char ch=getchar();
        int res=0,f=1;
        while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
        return res*f;
    }
    const int N=100005;
    const int mod=51061;
    inline void inc(int &a,int b){
        a=(a+b>=mod)?a+b-mod:a+b;
    }
    inline void mult(int &a,int b){
        a=(a*b)>=mod?a*b%mod:a*b;
    }
    namespace Lct{
        int q[N],rev[N],siz[N],add[N],mul[N],val[N],sum[N],son[N][2],fa[N];
        #define lc(u) son[u][0]
        #define rc(u) son[u][1]
        inline bool isrt(int u){
            if(!fa[u])return 1;
            return lc(fa[u])!=u&&rc(fa[u])!=u;
        }
        inline bool isrc(int u){
            return rc(fa[u])==u;
        }
        inline void pushup(int u){
            siz[u]=1,sum[u]=val[u];
            if(lc(u))siz[u]+=siz[lc(u)],inc(sum[u],sum[lc(u)]);
            if(rc(u))siz[u]+=siz[rc(u)],inc(sum[u],sum[rc(u)]);
        }
        inline void pushmul(int u,int k){
            mult(mul[u],k),mult(add[u],k),mult(val[u],k),mult(sum[u],k);
        }
        inline void pushadd(int u,int k){
            inc(add[u],k),inc(val[u],k),inc(sum[u],siz[u]*k%mod);
        }
        inline void pushdown(int u){
            if(rev[u]){
                if(lc(u))rev[lc(u)]^=1;
                if(rc(u))rev[rc(u)]^=1;
                swap(lc(u),rc(u)),rev[u]=0;
            }
            if(mul[u]!=1){
                pushmul(lc(u),mul[u]),pushmul(rc(u),mul[u]),mul[u]=1;
            }
            if(add[u]){
                pushadd(lc(u),add[u]),pushadd(rc(u),add[u]),add[u]=0;
            }
        }
        inline void rotate(int v){
            int u=fa[v],z=fa[u];
            int t=rc(u)==v;
            if(!isrt(u))son[z][rc(z)==u]=v;
            fa[v]=z;
            son[u][t]=son[v][t^1],fa[son[v][t^1]]=u;
            son[v][t^1]=u,fa[u]=v;
            pushup(u),pushup(v);
        }
        inline void splay(int u){
            q[q[0]=1]=u;
            for(int v=u;!isrt(v);v=fa[v])q[++q[0]]=fa[v];
            for(int i=q[0];i;i--)pushdown(q[i]);
            while(!isrt(u)){
                if(!isrt(fa[u])){
                    if(isrc(u)==isrc(fa[u]))rotate(fa[u]);
                    else rotate(u);
                }
                rotate(u);
            }
            pushup(u);
        }
        inline void access(int u){
            for(int v=0;u;v=u,u=fa[u]){
                splay(u),rc(u)=v;
                if(v)fa[v]=u;
                pushup(u);
            }
        }
        inline int findrt(int u){
            access(u),splay(u);
            while(pushdown(u),lc(u))u=lc(u);
            splay(u);return u;
        }
        inline void makert(int u){
            access(u),splay(u),rev[u]^=1;
        }
        inline void link(int u,int v){
            makert(u),fa[u]=v;
        }
        inline void cut(int u,int v){
            makert(u),access(v),splay(v);
            lc(v)=fa[u]=0,pushup(v);
        }
        inline void split(int u,int v){
            makert(u),access(v),splay(v);
        }
    }
    using namespace Lct;
    char op[5];
    int n,m;
    signed main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++)mul[i]=val[i]=1;
        for(int i=1;i<n;i++){
            int u=read(),v=read();
            link(u,v);
        }
        while(m--){
            scanf("%s",op);
            switch(op[0]){
                case '+':{
                    int u=read(),v=read(),k=read();
                    split(u,v),pushadd(v,k);
                    break;
                }
                case '-':{
                    int u=read(),v=read();
                    cut(u,v),u=read(),v=read();
                    link(u,v);
                    break;
                }
                case '/':{
                    int u=read(),v=read();
                    split(u,v),cout<<sum[v]<<'
    ';
                    break;
                }
                default:{
                    int u=read(),v=read(),k=read();
                    split(u,v),pushmul(v,k);
                    break;
                }
            }
        }
    }
    
  • 相关阅读:
    tcpip数据包编码解析(chunk and gzip)_space of Jialy_百度空间
    epoll 事件之 EPOLLRDHUP
    c What is the Difference Between read() and recv() , and Between send() and write()? Stack Overflow
    HTTP KeepAlive详解 IT心雪的日志 网易博客
    北京生活 TIPS 银行服务篇
    eventfdaiotest.c
    北京生活 TIPS 谈谈日常理财
    C语言抓http gzip包并解压 失败 C/C++ ChinaUnix.net
    转:javascript 对象和原型
    转:Javascript原型链和原型的一个误区
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145604.html
Copyright © 2020-2023  润新知