zoukankan      html  css  js  c++  java
  • BZOJ 2631 tree LCT

    题意:链接

    方法: LCT

    解析:

    挺简单好想的LCT

    首先依照题意link出一棵树

    接下来有四种操作,第一种是打一个加法标记。直接打就OK,另外一种是cut原来的一条边再link出一条新边。

    第三种是打一个乘法标记,(和bzoj1798好像)

    第四种是求u到v路径的权值和,这仅仅须要把v换成根,之后訪问x,把x splay上去,拿出来此时的sum[x]就是答案。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 100010
    #define mod 51061
    using namespace std;
    typedef unsigned int uint;
    char s[5];
    uint x,y;
    uint n,q;
    uint rt[N];
    uint rev[N];
    uint mul[N];
    uint add[N];
    uint sum[N];
    uint val[N]; 
    uint size[N];
    uint ch[N][2];
    uint fa[N];
    void init()
    {
        for(int i=1;i<=n;i++)mul[i]=1,rt[i]=1,size[i]=1,val[i]=1;
    }
    void pushdown_add_and_mul_operation(int x,int add_opt,int mul_opt)
    {
        sum[x]=(sum[x]*mul_opt+size[x]*add_opt)%mod;
        val[x]=(val[x]*mul_opt+add_opt)%mod;
        add[x]=(add[x]*mul_opt+add_opt)%mod;
        mul[x]=(mul[x]*mul_opt)%mod;
    } 
    void pushdown(uint x)
    {
        if(rev[x])
        {
            rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
            rev[x]^=1;
            swap(ch[x][0],ch[x][1]);
        }
        if(mul[x]!=1||add[x]!=0)
        {
            if(ch[x][0]!=0)
            {
                pushdown_add_and_mul_operation(ch[x][0],add[x],mul[x]);
            }
            if(ch[x][1]!=0)
            {
                pushdown_add_and_mul_operation(ch[x][1],add[x],mul[x]);
            }
            mul[x]=1,add[x]=0;
        }
    }
    void down(uint x)
    {
        if(!rt[x])down(fa[x]);
        pushdown(x);
    }
    void pushup(uint x)
    {
        size[x]=(size[ch[x][0]]+size[ch[x][1]]+1)%mod;
        sum[x]=(sum[ch[x][0]]+sum[ch[x][1]]+val[x])%mod;
    }
    void rotate(uint x)
    {
        uint y=fa[x],kind=ch[y][1]==x;
        ch[y][kind]=ch[x][!kind];
        fa[ch[y][kind]]=y;
        ch[x][!kind]=y;
        fa[x]=fa[y];
        fa[y]=x;
        if(rt[y])rt[y]=0,rt[x]=1;
        else ch[fa[x]][ch[fa[x]][1]==y]=x;
        pushup(y);
    }
    void splay(uint x)
    {
        down(x);
        while(!rt[x])
        {
            uint y=fa[x],z=fa[y];
            if(rt[y])rotate(x);
            else if((ch[y][1]==x)==(ch[z][1]==y))
            {
                rotate(y),rotate(x);
            }else rotate(x),rotate(x);
        }
        pushup(x);
    }
    void access(uint x)
    {
        uint y=0;
        while(x)
        {
            splay(x);
            rt[ch[x][1]]=1,rt[y]=0;
            ch[x][1]=y;
            pushup(x);
            y=x,x=fa[x];
        }
    }
    void movetoroot(uint x)
    {
        access(x);
        splay(x);
        rev[x]=1;
        pushdown(x);
    }
    void link(uint x,uint y)
    {
        movetoroot(x);
        fa[x]=y;
    }
    void cut(uint x,uint y)
    {
        movetoroot(x);
        access(y);
        splay(y);
        rt[x]=1;
        ch[y][0]=0;
        fa[x]=0;
    }
    int main()
    {
        scanf("%u%u",&n,&q);
        init();
        for(int i=1;i<n;i++)
        {
            scanf("%u%u",&x,&y);
            link(x,y);
        }
        for(int i=1;i<=q;i++)
        {
            scanf("%s",s);
            uint x,y,z,w;
            switch(s[0])
            {
                case '+':
                    scanf("%u%u%u",&x,&y,&z);
                    movetoroot(y);access(x);splay(x);
                    pushdown_add_and_mul_operation(x,z,1);
                    break;
                case '-':scanf("%u%u%u%u",&x,&y,&z,&w);cut(x,y);link(z,w);break;
                case '*': 
                    scanf("%u%u%u",&x,&y,&z);
                    movetoroot(y);access(x);splay(x);
                    pushdown_add_and_mul_operation(x,0,z);
                    break;
                case '/':
                    scanf("%u%u",&x,&y);
                    movetoroot(y);access(x);splay(x);
                    printf("%u
    ",sum[x]);
                    break;
            }
        }
    }
  • 相关阅读:
    Vue 应用 nginx 配置 前后端不分离模式
    解决使用antd Modal组件时数据污染问题
    关于antd怎么在父组件中控制子组件的表单提交
    Web前端工程师面试题1-1
    Web前端工程师面试题7-4
    react 的 生命周期
    字符串的方法
    栈的基本算法
    node.js 获取文件目录
    bat脚本文件启动UG NX软件,动态调用外挂,以及设置环境变量
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7072683.html
Copyright © 2011-2022 走看看