zoukankan      html  css  js  c++  java
  • bzoj 2631

    lct 基础(' '   ) 就当个纪念吧(' '    )  毕竟写了4h, cut 部分一直naive 总是想找谁是儿子,然后最后发现直接提根就好了啊(' '   )

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    const ll mod = 51061;
    const ll maxn = 100010;
    
    ll pl(ll a, ll b) {
        ll ret = a + b;
        if(ret >= mod) ret %= mod;
        return ret;
    }
    
    ll mul(ll a, ll b) {
        return a * b % mod;
    }
    
    struct node {
        ll ans, lm, lp, lr, size, data, p;
        node *son[2], *fa;
    }e[maxn]; ll ne = 0;
    
    void test(node* x) {
        if(!x) return;
        cout << x-> data <<" "<<x-> size <<" "<< x-> p << endl;
        for(ll i = 0; i < 2; ++ i) test(x-> son[i]);
    }
    
    void update(node* x) {
        x-> ans = x-> data, x-> size = 1;
        for(ll i = 0; i < 2; ++ i)
            if(x-> son[i]) 
                x-> ans = pl(x-> ans, x-> son[i]-> ans), x-> size = pl(x-> son[i]-> size, x-> size); 
    }
    
    void swap(node* &a, node* &b) {
        node* mid = a; a = b, b = mid;
    }
    
    void pushdown(node* x) {
        if(!x || (!x-> lp && !x-> lr && x-> lm == 1)) return;
        if(x-> lr) {
            swap(x-> son[0], x-> son[1]);
            for(ll i = 0; i < 2; ++ i) if(x-> son[i]) x-> son[i]-> lr ^= 1;
            x-> lr = 0;
        }
        for(ll i = 0; i < 2; ++ i) {
            if(x-> son[i]) { 
                x-> son[i]-> ans = pl(mul(x-> son[i]-> ans, x-> lm), mul(x-> son[i]-> size, x-> lp));
                x-> son[i]-> data = pl(mul(x-> son[i]->data, x-> lm), x-> lp);
                x-> son[i]-> lp = pl(mul(x-> son[i]-> lp, x-> lm), x-> lp);
                x-> son[i]-> lm = mul(x-> son[i]-> lm, x-> lm);
            }
        }
        x-> lm = 1, x-> lp = 0;  
    }
    
    void rotate(node* x, ll f) {
        node* y = x-> fa;
        if(y-> fa) {
            if(y-> fa-> son[0] == y) y-> fa-> son[0] = x;
            else y-> fa-> son[1] = x;
        }
        x-> fa = y-> fa; x-> size = y-> size; y-> fa = x; x-> p = y-> p;
        x-> ans = y-> ans; 
        y-> son[f] = x-> son[!f]; 
        if(x-> son[!f]) x-> son[!f]-> fa = y;
        x-> son[!f] = y;
        update(y);
    }
    
    void splay(node* x, node* f) {
        pushdown(x);
        while(x-> fa != f) {
            if(x-> fa-> fa == f) {
                pushdown(x-> fa-> fa), pushdown(x-> fa), pushdown(x);
                ll a = x-> fa-> son[0] == x ? 0 : 1;
                rotate(x, a);
            }
            else {
                node *y = x-> fa, *z = y-> fa;
                pushdown(z), pushdown(y), pushdown(x); 
                ll a = z-> son[0] == y ? 0 : 1;
                ll b = y-> son[0] == x ? 0 : 1;
                if(a == b) rotate(y, a), rotate(x, b);
                else rotate(x, b), rotate(x, a);
            }
        }
    }
    
    void access(ll cur) {
        node* x = e + cur; pushdown(x);
        node* y; splay(x, NULL);
        if(x-> son[1]) x-> son[1]-> p = cur, x-> son[1]-> fa = NULL, x-> son[1] = NULL;
        update(x);
        ll pp;
        while((pp = x-> p)) {
            y = e + pp; 
            splay(y, NULL); 
            if(y-> son[1]) y-> son[1]-> p = pp, y-> son[1]-> fa = NULL, y-> son[1] = NULL;
            y-> son[1] = x; 
            x-> fa = y;
            update(y);
            splay(x, NULL);
        }
    }
    
    void reserve(ll x) {
        access(x); 
        //test(x + e); cout << endl;
        (e + x)-> lr ^= 1;
    }
    
    ll n, m;
    
    void link(ll a, ll b) {
        access(a);
        reserve(b);
        (e + b)-> p = a;
        update(e + a), update(e + b);
    }
    
    void cut(ll a, ll b) {
        reserve(a), access(b);
        //test(b + e); cout << endl;
        (e + a)-> p = 0, (e + a)-> fa = NULL, (e + b)-> son[0] = NULL;
        update(e + a), update(e + b);
    }
    
    ll ll_get() {
        ll x = 0; char c = (char)getchar();
        while(!isdigit(c) && c != '-') c = (char)getchar();
        bool f = 0; if(c == '-') f = 1, c = (char)getchar();
        while(isdigit(c)) {
            x = x * 10 + (ll)(c - '0');
            c = (char)getchar();
        }
        if(f) x = -x;
        return x;
    }
    
    struct edge {
        ll t; edge* next;
    }se[maxn * 2], *head[maxn]; ll oe = 0;
    
    void addedge(ll f, ll t) {
        se[oe].t = t, se[oe].next = head[f], head[f] = se + oe ++;
    }
    
    bool vis[maxn];
    
    void build(ll x, ll pre) {
        vis[x] = 1;
        (e + x)-> p = pre; (e + x)-> data = (e + x)-> ans = 1; (e + x)-> size = 1; (e + x)-> lm = 1;
        for(edge* p = head[x]; p; p = p-> next) {
            if(!vis[p-> t]) build(p-> t, x);
        }
    }
    
    void read() {
        n = ll_get(), m = ll_get();
        for(ll i = 1; i < n; ++ i) {
            ll f = ll_get(), t = ll_get();
            addedge(f, t), addedge(t, f);
        }
        memset(vis, 0, sizeof(vis));
        build(1, 0);
    }
    
    void sov() {
        char s[10];
       // for(int i = 1; i <= n; ++ i) test(e + i), cout << endl;
            //cout << "****
    ";
        while(m --) {
            scanf("%s", s + 1); 
            if(s[1] == '+') {
                ll a = ll_get(), b = ll_get(), c = ll_get();
                reserve(a); access(b); 
                node* x = (e + b);
                x-> lp = pl(c, x-> lp), x-> ans = pl(x-> ans, mul(c, x-> size)), x-> data = pl(x-> data, c);
            }
            if(s[1] == '*') {
                ll a = ll_get(), b = ll_get(), c = ll_get();
                reserve(a);
                access(b);
                node* x = (e + b);
                x-> lm = mul(x-> lm, c), x-> ans = mul(x-> ans, c), x-> data = mul(x-> data, c), x-> lp = mul(x-> lp, c);
            }
            if(s[1] == '-') {
                ll a, b, c, d; a = ll_get(), b = ll_get(), c = ll_get(), d = ll_get();
                cut(a, b);
                //for(int i = 1; i <= n; ++ i) cout << (e + i)-> p << endl<< endl;
                //for(int i = 1; i <= n; ++ i) test(e + i), cout << endl;
            //cout << "****
    ";
                link(c, d);
    
                //for(int i = 1; i <= n; ++ i) test(e + i), cout << endl;
            
            }
            if(s[1] == '/') {
                ll a, b; a = ll_get(), b = ll_get(); 
                reserve(a), access(b); 
                printf("%lld
    ", (e + b)-> ans);
            }
            //for(int i = 1; i <= n; ++ i) test(e + i), cout << endl;
            //cout << "****
    ";
            //cout << (e + 1)-> son[0] << endl;
        }
    }
    
    int main() {
        //freopen("test.in", "r", stdin);
        //freopen("test.out", "w", stdout);
        read(); 
        sov();
    }
    
  • 相关阅读:
    BeautifulSoup模块
    爬取校花网视频
    爬虫基本原理
    python学习笔记-50 使用SQLAlchemy
    python学习笔记-49 使用MySQL
    PTA天梯 L3-007 天梯地图
    VS2013 创建ASP.NET MVC 4.0 未指定的错误(异常来自HRESULT: 0x80004005(e_fail))
    动态规划--新手
    文件上传绕过
    C# → 数据库
  • 原文地址:https://www.cnblogs.com/ianaesthetic/p/4207124.html
Copyright © 2011-2022 走看看