码迷,mamicode.com
首页 > 其他好文 > 详细

可持久化平衡树

时间:2020-08-28 14:34:02      阅读:43      评论:0      收藏:0      [点我收藏+]

标签:long   int   break   key   swa   hide   cas   ace   namespace   

技术图片
#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\n", 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

 

可持久化平衡树

标签:long   int   break   key   swa   hide   cas   ace   namespace   

原文地址:https://www.cnblogs.com/ctyakwf/p/13550334.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!