zoukankan      html  css  js  c++  java
  • BZOJ_2631_tree_LCT

    BZOJ_2631_tree_LCT

    Description

     一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
    + u v c:将u到v的路径上的点的权值都加上自然数c;
    - u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
    * u v c:将u到v的路径上的点的权值都乘上自然数c;
    / u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。

    Input

      第一行两个整数n,q
    接下来n-1行每行两个正整数u,v,描述这棵树
    接下来q行,每行描述一个操作

    Output

      对于每个/对应的答案输出一行

    Sample Input

    3 2
    1 2
    2 3
    * 1 3 4
    / 1 1

    Sample Output

    4

    HINT

    数据规模和约定

    10%的数据保证,1<=n,q<=2000

    另外15%的数据保证,1<=n,q<=5*10^4,没有-操作,并且初始树为一条链

    另外35%的数据保证,1<=n,q<=5*10^4,没有-操作

    100%的数据保证,1<=n,q<=10^5,0<=c<=10^4


     LCT模板题。注意乘法和加法下传的顺序。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 100050
    #define mod 51061
    #define ls ch[p][0]
    #define rs ch[p][1]
    #define get(x) (ch[f[x]][1]==x)
    typedef unsigned int ui;
    int n,m,ch[N][2],f[N],rev[N];
    ui sum[N],mul[N],add[N],siz[N],val[N];
    char opt[10];
    inline bool isrt(int x) {
        return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;
    }
    void pushdown(int p) {
        if(mul[p]!=1) {
            ui u=mul[p];
            sum[ls]=sum[ls]*u%mod; mul[ls]=mul[ls]*u%mod; add[ls]=add[ls]*u%mod; val[ls]=val[ls]*u%mod;
            sum[rs]=sum[rs]*u%mod; mul[rs]=mul[rs]*u%mod; add[rs]=add[rs]*u%mod; val[rs]=val[rs]*u%mod;
            mul[p]=1;
        }
        if(add[p]) {
            ui d=add[p];
            sum[ls]=(sum[ls]+siz[ls]*d%mod)%mod; add[ls]=(add[ls]+d)%mod; val[ls]=(val[ls]+d)%mod;
            sum[rs]=(sum[rs]+siz[rs]*d%mod)%mod; add[rs]=(add[rs]+d)%mod; val[rs]=(val[rs]+d)%mod;
            add[p]=0;
        }
        if(rev[p]) {
            swap(ch[ls][0],ch[ls][1]);
            swap(ch[rs][0],ch[rs][1]);
            rev[ls]^=1; rev[rs]^=1;
            rev[p]=0;
        }
        /*cal(ls , add[p] , mul[p] , rev[p]);
        cal(rs , add[p] , mul[p] , rev[p]);
        add[p] = rev[p] = 0 , mul[p] = 1;*/
    }
    void pushup(int p) {
        siz[p]=siz[ls]+siz[rs]+1;
        sum[p]=(sum[ls]+sum[rs]+val[p])%mod;
    }
    void update(int p) {
        if(!isrt(p)) update(f[p]);
        pushdown(p);
    }
    void rotate(int x) {
        int y=f[x],z=f[y],k=get(x);
        if(!isrt(y)) ch[z][ch[z][1]==y]=x;
        ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
        ch[x][!k]=y; f[y]=x; f[x]=z;
        pushup(y); pushup(x);
    }
    void splay(int x) {
        update(x);
        for(int fa;fa=f[x],!isrt(x);rotate(x))
            if(!isrt(fa))
                rotate(get(fa)==get(x)?fa:x);
    }
    void access(int p) {
        int t=0;
        while(p) splay(p),rs=t,pushup(p),t=p,p=f[p];
    }
    void makeroot(int p) {
        access(p); splay(p); swap(ls,rs); rev[p]^=1;
    }
    void link(int x,int p) {
        makeroot(x); f[x]=p;
    }
    void cut(int x,int p) {
        makeroot(x); access(p); splay(p); ls=f[x]=0;
    }
    void split(int x,int p) {
        makeroot(x); access(p); splay(p);
    }
    int main() {
        scanf("%d%d",&n,&m);
        int i,x,y,z,w;
        for(i=1;i<=n;i++) val[i]=mul[i]=siz[i]=sum[i]=1;
        for(i=1;i<n;i++) {
            scanf("%d%d",&x,&y); link(x,y);
        }
        for(i=1;i<=m;i++) {
            scanf("%s%d%d",opt,&x,&y);
            int p=y;
            if(opt[0]=='+') {
                scanf("%d",&z); split(x,p);
                sum[p]=(sum[p]+siz[p]*z%mod)%mod;
                val[p]=(val[p]+z)%mod;
                add[p]=(add[p]+z)%mod;
                //cal(p,z,1,0);
            }else if(opt[0]=='-') {
                scanf("%d%d",&z,&w); cut(x,y); link(z,w);
            }else if(opt[0]=='*') {
                scanf("%d",&z); split(x,p);
                sum[p]=sum[p]*z%mod;
                val[p]=val[p]*z%mod;
                add[p]=add[p]*z%mod;
                mul[p]=mul[p]*z%mod;
                //cal(p,0,z,0);
            }else {
                split(x,p); printf("%u
    ",sum[p]);
            }
        }
    }
    
  • 相关阅读:
    Elkstack2.0部署
    ZABBIX自定义用户KEY与参数USERPARAMETERS监控脚本输出
    elasticsearch 管理工具
    指定时间开启、结束定时器
    异步的作用
    快速生成几百万条测试数据
    查看查询索引
    蠕虫复制
    导出数据库
    header
  • 原文地址:https://www.cnblogs.com/suika/p/8967893.html
Copyright © 2011-2022 走看看