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\n",Query(&null[x1],&null[x2]));
        }
    }
    return 0;
}
posted @ 2017-10-26 17:40  cooook  阅读(125)  评论(0编辑  收藏  举报