zoukankan      html  css  js  c++  java
  • BZOJ2631 LCT

    这是道LCT裸题,但是好像会炸int <-- 这个傻逼调了半个小时...
    写LCT的时候需要注意在Make_root的时候记得Splay....
    至于标记的问题我是这么处理的:
    对于后来的乘法标记,同时把加法标记乘上相应的值,这样在最后Push_down的时候就要先处理乘法标记再处理加法标记

    Code:

    #include <stdio.h>
    #include <iostream>
    #define int long long 
    const int mod = 51061,MAXN = 100005;
    int n,q;
    
    
    template <typename _t>
    inline _t read() {
        _t x = 0, f = 1;
        char ch = getchar();
        for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -f;
        for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + (ch ^ 48);
        return x * f;
    }
    
    struct node{
        node *ch[2],*f;
        int tag,size,sum,mul,add,val;
        inline void Maintain();
        inline void Push_down();
        inline void rev();
        inline void Splay();
        inline void rotate();
        inline bool isrt();
        inline bool get();
        inline void Mul(int);
        inline void Add(int);
    }null[MAXN];
    
    inline bool node::isrt() {
        return f -> ch[0] != this && f -> ch[1] != this;
    }
    
    inline bool node::get() {
        return f -> ch[1] == this;
    }
    
    inline void node::rev() {
        if (this == null) return ;
        tag ^= 1;
        std::swap(ch[0],ch[1]);
    }
    
    inline void node::Add(int x) {
        if (this == null) return ;
        (val += x) %= mod;
        (add += x) %= mod;
        (sum += x * size % mod) %= mod;
    }
    
    inline void node::Mul(int x) {
        if (this == null) return ;
        (sum *= x) %= mod;
        (mul *= x) %= mod;
        (add *= x) %= mod;
        (val *= x) %= mod;
    }
    
    inline void node::Maintain() {
        if (this == null) return ;
        sum = (ch[0] -> sum + ch[1] -> sum + val) % mod;
        size = ch[0] -> size + ch[1] -> size + 1;
    }
    
    inline void node::Push_down() {
        if (this == null) return;
        if (mul != 1) {
            ch[0] -> Mul(mul);
            ch[1] -> Mul(mul);
            mul = 1;
        }
        if (add) {
            ch[0] -> Add(add);
            ch[1] -> Add(add);
            add = 0;
        }
        if (tag) {
            tag ^= 1;
            ch[0] -> rev();
            ch[1] -> rev();
        }
    }
    
    inline void node::rotate() {
        node *fa = f, *pa = fa -> f; 
        pa -> Push_down(); fa -> Push_down(); Push_down(); int d = get();
        if (!f -> isrt()) pa -> ch[f -> get()] = this;
        if ((f -> ch[d] = ch[d^1]) != null) ch[d^1] -> f = fa;
        this -> f = pa; fa -> f = this; ch[d^1] = fa;
        fa -> Maintain(); Maintain();
    }
    
    inline void node::Splay() {
        Push_down();
        for (node *t = f; !isrt(); rotate(),t = f)
            if (!t -> isrt()) {
                t -> f -> Push_down(); t -> Push_down(); Push_down();
                if (t -> get() == get()) t -> rotate();
                else rotate();
            }
            else t -> Push_down(),Push_down();
    }
    
    inline void Access(node *x) {
        node *y = null;
        while (x != null)
            x -> Splay(),
            x -> ch[1] = y,
            x -> Maintain(),
            y = x,x = x -> f;
    }
    
    inline void Make_root(node *x) {
        Access(x); x -> Splay(); x -> rev();
    }
    
    inline void Link(node *x,node *y) {
        Make_root(x); x -> Splay(); x -> f = y;
    }
    
    inline void Cut(node *x,node *y) {
        Make_root(x); Access(y); y -> Splay();
        y -> ch[0] = x -> f = null;
        y -> Maintain();
    }
    
    inline void Update(node *x,node *y,int c) {
        Make_root(x); Access(y); y -> Splay();
        y -> Add(c % mod);
    }
    
    inline void Mul(node *x,node *y,int c) {
        Make_root(x); Access(y); y -> Splay();
        y -> Mul(c % mod);
    }
    
    inline int Query(node *x,node *y) {
        Make_root(x); Access(y);  y -> Splay();
        return y -> sum;
    }
    
    inline int read_char() {
        char ch =getchar();
        for (; ch != '+' && ch != '-' && ch != '*' && ch != '/'; ch = getchar());
        switch (ch) {
            case '+':return 1;
            case '-':return 2;
            case '*':return 3;
            case '/':return 4;
        }
    }
    
    signed main() {
        n = read<int>(); q = read<int>();
        null -> ch[0] = null -> ch[1] = null -> f = null; null -> mul = 0;
        null -> size = null -> tag = null -> sum = null -> add = null -> val = 0;
        for (int i = 1; i <= n; i++) 
            null[i].ch[0] = null[i].ch[1] = null[i].f = null,
            null[i].mul = 1,null[i].val = 1,null[i].sum = 1,
            null[i].tag = 0,null[i].size = 1,null[i].add = 0;
        for (int i = 1,u,v; i < n; i++) {
            u = read<int>(),v = read<int>();
            Link(&null[u],&null[v]);
        }
        while (q--) {
            register int op = read_char(),x1,x2,x3,x4;
            if (op == 1) {
                x1 = read<int>(),x2 = read<int>(),x3 = read<int>();
                Update(&null[x1],&null[x2],x3);
            }
            if (op == 2) {
                x1 = read<int>(); x2 = read<int>(); x3 = read<int>(); x4 = read<int>();
                Cut(&null[x1],&null[x2]); Link(&null[x3],&null[x4]);
            } 
            if (op == 3) {
                x1 = read<int>(),x2 = read<int>(),x3 = read<int>();
                Mul(&null[x1],&null[x2],x3);
            }
            if (op == 4) {
                x1 = read<int>(),x2 = read<int>();
                printf("%lld
    ",Query(&null[x1],&null[x2]));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Nginx log日志参数详解
    sea.js模块加载工具
    sea.js模块加载工具
    Airbnb React/JSX 编码规范
    4.2 react patterns(转)
    4.1 react 代码规范
    3.5 compose redux sages
    3.3 理解 Redux 中间件(转)
    3.4 redux 异步
    3.1 开始使用 redux
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738063.html
Copyright © 2011-2022 走看看