• 可持久化平衡树


    #include <bits/stdc++.h>
    #define INF (1<<25)
    #define MAXN 200005
    #define getSZ(p) (p?p->sz:0)
    #define getSUM(p) (p?p->sum:0)
    using namespace std;
    typedef long long ll;
    
    struct Node{
        int rk,key,sz,rev;
        ll sum;
        Node *ls, *rs;
    
        void update(){
            sum = getSUM(ls) + getSUM(rs) + key;
            sz = getSZ(ls) + getSZ(rs) + 1;
        }
    
    } pool[100*MAXN], *rt[MAXN];
    
    int top = 0;
    
    Node* buildNode(int x);
    
    void split(Node* p, Node*& pL, Node*& pR, int x);
    void merge(Node*& p, Node* pL, Node* pR);
    
    void insert(Node*& p, int id, int x);
    void remove(Node*& p, int x);
    
    void reverse(Node*& p, int l, int r);
    ll query(Node*& p, int l, int r);
    
    int N,T;
    
    int main(){
    
        scanf("%d", &T);
        int v, opt, id, x, l, r;
        ll lastans = 0;
        for(int t=1;t<=T;t++){
            scanf("%d%d", &v, &opt);
            rt[t] = rt[v];
    
            switch(opt){
                case 1:
                    scanf("%d%d", &id, &x);
                    id ^= lastans; x ^= lastans;
                    insert(rt[t], id, x);
                    break;
                case 2:
                    scanf("%d", &id);
                    id ^= lastans;
                    remove(rt[t], id);
                    break;
                case 3:
                    scanf("%d%d", &l, &r);
                    l ^= lastans; r ^= lastans;
                    reverse(rt[t], l, r);
                    break;
                case 4: 
                    scanf("%d%d", &l, &r);
                    l ^= lastans; r ^= lastans;
    
                    lastans = query(rt[t], l ,r);
                    printf("%lld
    ", lastans);
                    break;
    
            }
        }
        return 0;
    }
    
    Node* copyNode(Node* rt){
        if(!rt) return NULL;
        Node *p = pool + (++top);
        pool[top] = *rt;
        return p;
    }
    
    void pushD(Node*& p){
        if(!p->rev) return;
        if(p->ls){
            p->ls = copyNode(p->ls);
            p->ls->rev ^= 1;
        }
    
        if(p->rs){
            p->rs = copyNode(p->rs);
            p->rs->rev ^= 1;
        }
    
        p->rev = 0;
        swap(p->ls, p->rs);
    }
    
    void split(Node* p, Node*& pL, Node*& pR, int k){
    
        if(!p){
            pL = pR = 0;
            return;
        }
    
        pushD(p);
        if(getSZ(p->ls)+1 <= k){
            pL = copyNode(p);
            split(p->rs, pL->rs, pR, k - (getSZ(p->ls)+1));
            pL->update();
        }
        else{
            pR = copyNode(p);
            split(p->ls, pL, pR->ls, k);
            pR->update();
        }
    }
    
    void merge(Node*& p, Node* pL, Node* pR){
        if(!pL || !pR){
            p = pL?pL:pR;
            return;
        }
    
        if(pL->rk < pR->rk){
            pushD(pL);
            p = pL;
            merge(p->rs, pL->rs, pR);
        }
        else{
            pushD(pR);
            p = pR;
            merge(p->ls, pL, pR->ls);
        }
        p->update();
    }
    
    Node* newNode(int x){
        Node* p = pool + (++top);
        p->key = p->sum = x;
        p->rk = rand();
        p->sz = 1;
        return p;
    }
    
    void insert(Node*& rt, int id, int x){
        Node *p1, *p2;
        split(rt, p1, p2, id);
        merge(rt, p1, newNode(x));
        merge(rt, rt, p2);
    }
    
    void remove(Node*& rt, int id){
        Node *p1, *p2, *p3, *p4;
        split(rt, p1, p2, id-1);
        split(p2, p3, p4, 1);
        merge(rt, p1, p4);
    }
    
    void reverse(Node*& rt, int l, int r){
        Node *p1, *p2, *p3, *p4;
        split(rt, p1, p2, l-1);
        split(p2, p3, p4, r-l+1);
        p3->rev ^= 1;
        merge(p2, p3, p4);
        merge(rt, p1, p2);
    }
    
    ll query(Node*& rt, int l, int r){
        Node *p1, *p2, *p3, *p4;
        split(rt, p1, p2, l-1);
        split(p2, p3, p4, r-l+1);
        ll ans = p3->sum;
        merge(p2, p3, p4);
        merge(rt, p1, p2);
        return ans;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    Tomcat架构解析(五)-----Tomcat的类加载机制
    session与cookie
    freemarker常用标签解释遍历
    freemarker常用标签解释三
    freemarker常用标签解释二
    freemarker常用标签解释
    禁止浏览器自动填充
    使用cookie实现自动登录
    长连接和短连接
    filter防止xxs攻击
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13550334.html
Copyright © 2020-2023  润新知