06_面向物件高階篇_01
阿新 • • 發佈:2020-08-23
#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; szView Code= 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, intl, 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; }