Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //misaka will carry me to master
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <utility>
- #include <cassert>
- #include <algorithm>
- #include <vector>
- #include <functional>
- #include <numeric>
- #include <set>
- #include <map>
- #define ll long long
- #define lb long double
- #define sz(vec) ((int)(vec.size()))
- #define all(x) x.begin(), x.end()
- #define pb push_back
- #define mp make_pair
- #define kill(x, s) {int COND = x; if(COND){ cout << s << "\n"; return ; }}
- const lb eps = 1e-9;
- //const ll mod = 1e18, ll_max = 1e18;
- const ll mod = (1 << (23)) * 119 +1, ll_max = 1e18;
- const int MX = 'HUG', int_max = 0x3f3f3f3f;
- struct {
- template<class T>
- operator T() {
- T x; std::cin >> x; return x;
- }
- } in;
- using namespace std;
- unsigned long nrng(void) {
- static unsigned long x=123456789, y=362436069, z=521288629;
- unsigned long t;
- x ^= x << 16;
- x ^= x >> 5;
- x ^= x << 1;
- t = x;
- x = y;
- y = z;
- z = t ^ x ^ y;
- return z;
- }
- //#define lc c[0]
- //#define rc c[1]
- #define ile(u) (tr[tr[u].par].lc != u)
- struct treap{
- struct value{
- ll val; int sz;
- ll aggr;
- value(){val = sz = 0; aggr = 0ll;}
- value(ll c, ll b, int s){val = c, aggr = b, sz = s; }
- void operator = (const value& b) { val = b.val; sz = b.sz; aggr = b.aggr; }
- };
- struct tag{
- int rev;
- tag(){ rev = 0;}
- tag(int a){ rev = a;}
- void operator = (const tag& b){ rev = b.rev; }
- tag operator * (const tag& b) const{
- return tag(rev^b.rev);
- }
- bool isid() const{ return (rev == 0); }
- } ;
- struct node{
- int pr;
- int lc, rc;
- value v;
- tag t;
- node(){ lc = rc = 0; pr = nrng();}
- void operator = (const node& b){
- //node tmp;
- lc = b.lc;
- rc = b.rc;
- v = b.v;
- t = b.t;
- pr = b.pr;
- //return *this;
- }
- } zero;
- void pull(int& u){
- tr[u].v.aggr = (tr[tr[u].lc].v.aggr + tr[tr[u].rc].v.aggr + tr[u].v.val);
- tr[u].v.sz = tr[tr[u].lc].v.sz + tr[tr[u].rc].v.sz + 1;
- }
- void apply(int& u, const tag& t){
- if(!u) return ;
- u = dup(u);
- tr[u].t = t * tr[u].t;
- //tr[u].v = t + tr[u].v;
- }
- void push(int& u){
- if((!u) || tr[u].t.isid()) return ;
- apply(tr[u].lc, tr[u].t);
- apply(tr[u].rc, tr[u].t);
- if(tr[u].t.rev){
- swap(tr[u].lc, tr[u].rc);
- }
- tr[u].t = tag();
- }
- vector<node> tr;
- int zs, ind;
- vector<int> st;
- treap(){
- zs = ind = 0;
- zero = node();
- zero.t = tag();
- zero.v = value();
- tr.pb(zero);
- }
- int nd(int k = 0){
- int x;
- //if(zs){ x = st.back(); st.pop_back(); }
- //else x = ++ind;
- x = ++ind;
- tr.pb(node());
- tr[x].v = value(k, k, 1);
- tr[x].t = tag();
- tr[x].pr = nrng();
- return x;
- }
- int dup(int& k){
- int a = ++ind;
- node tmp = tr[k];
- tr.pb(tmp);
- return a;
- }
- void pop(int x){
- tr[x] = zero;
- st.pb(x);
- }
- void split(int x, int k, int& L, int& R){
- static string TT;
- if(!x){ L = R = 0; return ;}
- push(x);
- int dist = tr[tr[x].lc].v.sz ;
- if(dist < k){
- L = dup(x);
- split(tr[L].rc, k - dist - 1, tr[L].rc, R);
- pull(L);
- }else{
- R = dup(x);
- split(tr[R].lc, k, L, tr[R].lc);
- pull(R);
- }
- }
- int merge(int& L, int& R){
- if(min(L, R) == 0) return L^R;
- push(L); push(R);
- if(tr[L].pr > tr[R].pr){
- tr[L].rc = merge(tr[L].rc, R);
- pull(L);
- return L;
- }else{
- tr[R].lc = merge(L, tr[R].lc);
- pull(R);
- return R;
- }
- }
- void merge(int& rt, int& L, int& R){
- rt = merge(L, R);
- }
- void pr(int rt){
- static int dep = 0;
- if(dep == 0) cout << rt << ": ";
- if(!rt) return ;
- dep++;
- //push(rt);
- pr(tr[rt].lc);
- //if(tr[rt].v.val)
- cout << "(" << rt << ", " << tr[rt].v.val << ") ";
- //cout << tr[rt].v.val << " " ;
- pr(tr[rt].rc);
- dep--;
- if(dep == 0) cout << "\n";
- }
- };
- //#undef lc
- //#undef rc
- //#undef ile
- int root[MX];
- void solve(){
- int n, q;
- cin >> q;
- treap bbst = treap();
- bbst.tr.reserve(30000000 +10);
- ll last= 0;
- for(int i = 1; i<=q; i++){
- int ver = in;
- int op = in;
- root[i] = root[ver];
- int rt = root[i];
- if(op == 1){
- ll ind, val;
- cin >> ind >> val;
- ind ^= last;
- val ^= last;
- int t1 = 0, t2 = 0;
- bbst.split(rt, ind, t1, t2);
- int t3 = bbst.nd(val), t4 = 0, t5 = 0;
- bbst.merge(t4, t1, t3);
- bbst.merge(t5, t4, t2);
- rt = t5;
- }else if(op == 2){
- ll ind;
- cin >> ind;
- ind ^= last;
- int t1, t2;
- bbst.split(rt, ind-1, t1, t2);
- int t3, t4;
- bbst.split(t2, 1, t3, t4);
- bbst.merge(rt, t1, t4);
- }else if(op == 3){
- ll l = in, r = in;
- l ^= last;
- r ^= last;
- int t1 = 0, t2 = 0;
- bbst.split(rt, r, t1, t2);
- int t3, t4, t5;
- bbst.split(t1, l-1, t3, t4);
- bbst.apply(t4, treap::tag(1));
- bbst.merge(t5, t3, t4);
- bbst.merge(rt, t5, t2);
- }else{
- ll l = in, r = in;
- l ^= last;
- r ^= last;
- //l--, r--;
- int t1 = 0, t2 = 0;
- bbst.split(rt, r, t1, t2);
- int t3, t4;
- bbst.split(t1, l-1, t3, t4);
- ll ans = bbst.tr[t4].v.aggr;
- int t5, t6;
- bbst.merge(t5, t3, t4);
- bbst.merge(t6, t5, t2);
- rt = t6;
- cerr << "query: ";
- last = ans;
- cout << ans << "\n";
- }
- root[i] = rt;
- if(i <= 100) cerr << "pkinghiiiiiiii\n";
- assert(bbst.tr[0].v.val == 0);
- }
- }
- int main(){
- cin.tie(0) -> sync_with_stdio(0);
- int T = 1;
- //cin >> T;
- for(int i = 1; i<=T; i++){
- solve();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement