1、题目大意:bzoj1798的lct版本

2、分析:这个把线段树改成splay就好

#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
namespace LinkCutTree{
    struct Node{
        Node *ch[2], *fa;
        LL sum, num;
        LL size;
        bool rev;
        LL mul, plu; 

        inline int which();

        inline void reverse(){
            if(this) rev ^= 1;
        }

        inline void pd();

        inline void maintain(){
            sum = (num + ch[0] -> sum + ch[1] -> sum) % 51061;
            size = (1 + ch[0] -> size + ch[1] -> size) % 51061;
        }

        Node();
    } *null = new Node, tree[100010], *pos[100010];

    Node::Node(){
        num = sum = 1;
        rev = false;
        ch[0] = ch[1] = fa = null;
        mul = 1;
        plu = 0;
        size = 1;
    }

    inline void Node::pd(){
            if(rev){
                swap(ch[0], ch[1]);
                ch[0] -> reverse();
                ch[1] -> reverse();
                rev = false;
            }
            if(ch[0] != null){
                ch[0] -> mul *= mul;
                ch[0] -> plu *= mul;
                ch[0] -> plu += plu;
                ch[0] -> num *= mul;
                ch[0] -> num += plu;
                ch[0] -> sum *= mul;
                ch[0] -> sum += plu * ch[0] -> size;
                ch[0] -> mul %= 51061;
                ch[0] -> plu %= 51061;
                ch[0] -> num %= 51061;
                ch[0] -> sum %= 51061;
            }
            if(ch[1] != null){
                ch[1] -> mul *= mul;
                ch[1] -> plu *= mul;
                ch[1] -> plu += plu;
                ch[1] -> num *= mul;
                ch[1] -> num += plu;
                ch[1] -> sum *= mul;
                ch[1] -> sum += plu * ch[1] -> size;
                ch[1] -> mul %= 51061;
                ch[1] -> plu %= 51061;
                ch[1] -> num %= 51061;
                ch[1] -> sum %= 51061;
            }
            mul = 1;
            plu = 0;
    }

    inline int Node::which(){
        if(fa == null || (this != fa -> ch[0] && this != fa -> ch[1])) return -1;
        return this == fa -> ch[1];
    }

    inline void rotate(Node *o){
        Node *p = o -> fa;
        int l = o -> which(), r = l ^ 1;
        o -> fa = p -> fa;
        if(p -> which() != -1) p -> fa -> ch[p -> which()] = o;
        p -> ch[l] = o -> ch[r];
        if(o -> ch[r]) o -> ch[r] -> fa = p;
        o -> ch[r] = p; p -> fa = o;
        o -> ch[r] -> maintain();
        o -> maintain();
    }

    inline void splay(Node *o){
        static stack<Node*> st;
        if(!o) return;
        Node *p = o;
        while(1){
            st.push(p);
            if(p -> which() == -1) break;
            p = p -> fa;
        }
        while(!st.empty()){
            st.top() -> pd(); st.pop();
        }

        while(o -> which() != -1){
            p = o -> fa;
            if(p -> which() != -1){
                if(p -> which() ^ o -> which()) rotate(o);
                else rotate(p);
            }
            rotate(o);
        }
    }

    inline void Access(Node *o){
        Node *y = null;
        while(o != null){
            splay(o);
            o -> ch[1] = y;
            o -> maintain();
            y = o; o = o -> fa;
        }
    }

    inline void MovetoRoot(Node *o){
        Access(o);
        splay(o);
        o -> reverse();
    }

    inline Node* FindRoot(Node *o){
        Access(o);
        splay(o);
        while(o -> ch[0] != null) o = o -> ch[0];
        return o;
    }

    inline void Link(Node *x, Node *y){
        MovetoRoot(x);
        x -> fa = y;
    }

    inline void Cut(Node *x, Node *y){
        MovetoRoot(x);
        Access(y);
        splay(y);
        y -> ch[0] = x -> fa = null;
        y -> maintain();
    }
}
int main(){
    using namespace LinkCutTree;
    null -> mul = 1;
    null -> size = 0;
    null -> plu = 0;
    null -> sum = 0;
    null -> num = 0;
    null -> ch[0] = null -> ch[1] = null -> fa = NULL;
    int n, q;
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; i ++) pos[i] = &tree[i];
    for(int i = 1; i < n; i ++){
        int u, v;
        scanf("%d%d", &u, &v);
        Link(pos[u], pos[v]);
    }
    char op[5];
    int x1, y1, x2, y2, c;
    while(q --){
        scanf("%s", op);
        if(op[0] == '+'){
            scanf("%d%d%d", &x1, &y1, &c);
            MovetoRoot(pos[x1]);
            Access(pos[y1]);
            splay(pos[y1]);
            pos[y1] -> num += c;
            pos[y1] -> num %= 51061;
            pos[y1] -> sum += pos[y1] -> size * c;
            pos[y1] -> sum %= 51061;
            pos[y1] -> plu += c;
            pos[y1] -> plu %= 51061;
        }
        else if(op[0] == '-'){
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            Cut(pos[x1], pos[y1]);
            Link(pos[x2], pos[y2]);
        }
        else if(op[0] == '*'){
            scanf("%d%d%d", &x1, &y1, &c);
            MovetoRoot(pos[x1]);
            Access(pos[y1]);
            splay(pos[y1]);
            pos[y1] -> num *= c;
            pos[y1] -> num %= 51061;
            pos[y1] -> sum *= c;
            pos[y1] -> sum %= 51061;
            pos[y1] -> mul *= c;
            pos[y1] -> mul %= 51061;
            pos[y1] -> plu *= c;
            pos[y1] -> plu %= 51061;
        }
        else{
            scanf("%d%d", &x1, &y1);
            MovetoRoot(pos[x1]);
            Access(pos[y1]);
            splay(pos[y1]);
            pos[y1] -> sum %= 51061;
            printf("%lld\n", pos[y1] -> sum);
        }
    }
    return 0;
}

BZOJ2631——tree的更多相关文章

  1. bzoj2631: tree

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  2. [BZOJ2631]tree 动态树lct

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 5171  Solved: 1754[Submit][Status][Discus ...

  3. [Link-Cut-Tree][BZOJ2631]Tree

    题面 Description: 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\(v\)的路径上的点的 ...

  4. bzoj2631 tree LCT 区间修改,求和

    tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 4962  Solved: 1697[Submit][Status][Discuss] Des ...

  5. bzoj2631: tree lct

    要打mul和add的lct 50000+的mod用unsigned int好了TAT (坑爹没打pc('\n');(静态)调了好久,样例竟然只输出一个,orz,也不提示PE T_T) #include ...

  6. BZOJ2631 tree(伍一鸣) LCT 秘制标记

    这个题一看就是裸地LCT嘛,但是我wa了好几遍,这秘制标记...... 注意事项:I.*对+有贡献 II.先下传*再下传+(因为我们已经维护了+,不能再让*对+产生贡献)III.维护+用到size # ...

  7. [bzoj2631]tree——lct

    Brief Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: u v c:将u到v的路径上的点的权值都加上自然数c: u1 v1 u2 ...

  8. BZOJ2631 tree 【LCT】

    题目 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的边( ...

  9. BZOJ2631: tree(LCT)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...

随机推荐

  1. Java Map 简介

    AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, H ...

  2. 添加JavaScrip

    本章内容: 加载外部脚本:添加嵌入脚本:JavaScrip事件 1,脚本类型:外部文件(使用纯文本格式)加载的脚本:嵌入在页面中的脚本. 加载外部脚本的方法 <body><scrip ...

  3. asp.net与Matlab类型转换(待补全)

    上上篇的博客已经提到如何配置环境,即如何在asp.net中调用matlab生成的dll文件.这篇博客打算做个笔记,那就是matlab和C#数据类型如何转换.随着需求的增加,我会不断增加新的类型转换. ...

  4. WinForm------DockManager控件的使用方法(里面包含DockPanel控件)

    1.在"引用"中添加DevExpress.XtraBars和DexExpress.XtraNavBar程序集 2.往工具栏拖出DockManager控件,点击右上角的小三角,再点击 ...

  5. elasticsearch api

    count curl -XGET http://21.3.5.121:9200/ipv4geo/service/_count -d '{"query":{"match&q ...

  6. Maven环境变量配置

    Maven 3.0.4版本下载地址: http://www.apache.org/dyn/closer.cgi?path=/maven/binaries/apache-maven-3.0.4-bin. ...

  7. mysql主从复制 转

    mysql服务器的主从配置,这样可以实现读写分离,也可以在主库挂掉后从备用库中恢复.需要两台机器,安装mysql,两台机器要在相通的局域网内,可以分布在不同的服务器上,也可以在一台服务器上启动多个服务 ...

  8. js 处理日期 看着比较全,备用

    http://www.cnblogs.com/endora/archive/2012/12/06/endorahe.html js 处理日期 看着比较全,备用

  9. 自然语言7_NLTK中文语料库sinica_treebank

    http://www.hankcs.com/program/python/nltk-chinese-corpus-sinica_treebank.html NLTK包含Sinica (中央研究院)提供 ...

  10. PNG类库

    libpng depends on Zlib http://www.libpng.org/pub/png/libpng.html LodePNG http://lodev.org/lodepng/ P ...