Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define NMAX 100010
- #define INF 1000000000
- #define fi first
- #define se second
- typedef pair< int, int > pll;
- pll invalid = {INF, INF};
- int newId = 0;
- typedef struct Treap
- {
- int y, val, me, tam;
- bool inv;
- Treap *pai, *lef, *rig;
- Treap(int pri, int v, bool status = false, Treap *p = NULL, Treap *l = NULL, Treap *r = NULL)
- {
- y = pri;
- val = v;
- me = v;
- inv = status;
- tam = 1;
- pai = p;
- lef = l;
- rig = r;
- }
- }Tr;
- Tr *node[NMAX];
- Tr *node2[2 * NMAX];
- int Size(Tr *root)
- {
- return (root == NULL) ? 0 : root->tam;
- }
- int GetVal(Tr *root)
- {
- return (root == NULL) ? INF : root->val;
- }
- int GetMin(Tr *root)
- {
- return (root == NULL) ? INF : root->me;
- }
- void UpdatePai(Tr *root, Tr *p)
- {
- if(root != NULL) root->pai = p;
- return;
- }
- void ChangeInv(Tr *root)
- {
- if(root != NULL) root->inv ^= true;
- return;
- }
- void Lazy(Tr *root)
- {
- if(root == NULL) return;
- if(root->inv == true)
- {
- swap(root->lef, root->rig);
- ChangeInv(root->lef);
- ChangeInv(root->rig);
- root->inv = false;
- }
- return;
- }
- void Recalc(Tr *root, int who)
- {
- if(root == NULL) return;
- if(who == 0) node[root->val] = root;
- if(who == 2) node2[root->val] = root;
- root->tam = Size(root->lef) + 1 + Size(root->rig);
- UpdatePai(root->lef, root);
- UpdatePai(root->rig, root);
- root->me = min(root->val, min(GetMin(root->lef), GetMin(root->rig)));
- return;
- }
- void Print(Tr *root)
- {
- Lazy(root);
- if(root == NULL) return;
- Print(root->lef);
- cout << abs(root->val) << " ";
- Print(root->rig);
- return;
- }
- Tr* Merge(Tr* l, Tr* r, int who)
- {
- Recalc(l, who);
- Recalc(r, who);
- Lazy(l);
- Lazy(r);
- if(l == NULL) return r;
- if(r == NULL) return l;
- Tr *novo;
- if(l->y > r->y)
- {
- novo = new Treap(l->y, l->val, l->inv, l->pai, l->lef, Merge(l->rig, r, who));
- }else
- {
- novo = new Treap(r->y, r->val, r->inv, r->pai, Merge(l, r->lef, who), r->rig);
- }
- Recalc(novo, who);
- return novo;
- }
- void Split(Tr* root, int idx, Tr **l, Tr **r, int who)
- {
- Recalc(root, who);
- Lazy(root);
- if(root == NULL)
- {
- *l = NULL;
- *r = NULL;
- return;
- }
- Tr *novo;
- int tl = Size(root->lef);
- if(tl + 1 <= idx)
- {
- Split(root->rig, idx - (tl + 1), &novo, r, who);
- *l = new Treap(root->y, root->val, root->inv, root->pai, root->lef, novo);
- Recalc(*l, who);
- }else
- {
- Split(root->lef, idx, l, &novo, who);
- *r = new Treap(root->y, root->val, root->inv, root->pai, novo, root->rig);
- Recalc(*r, who);
- }
- return;
- }
- void Add(Tr **rootId, Tr **rootVal, Tr **rootInOut, int pos1, int pos2, int val)
- {
- Tr *m, *m1, *m2, *l, *r;
- m = new Treap(rand() % NMAX, newId);
- Split(*rootId, pos1, &l, &r, 0);
- *rootId = Merge(Merge(l, m, 0), r, 0);
- m = new Treap(rand() % NMAX, val);
- Split(*rootVal, pos1, &l, &r, 1);
- *rootVal = Merge(Merge(l, m, 1), r, 1);
- m1 = new Treap(rand() % NMAX, newId);
- m2 = new Treap(rand() % NMAX, newId + NMAX);
- m = Merge(m1, m2, 2);
- Split(*rootInOut, pos2, &l, &r, 2);
- *rootInOut = Merge(Merge(l, m, 2), r, 2);
- newId++;
- return;
- }
- void Invert(Tr **root, int a, int b)
- {
- Tr *l, *r, *m, *aux;
- Split(*root, a, &l, &aux, 1);
- Split(aux, b - a + 1, &m, &r, 1);
- ChangeInv(m);
- *root = Merge(Merge(l, m, 1), r, 1);
- return;
- }
- int GetPos(Tr *root)
- {
- if(root->pai == NULL) return 0;
- if(root->pai->lef == root) return GetPos(root->pai);
- else return GetPos(root->pai) + Size(root->pai->lef) + 1;
- }
- int GetPos(int u)
- {
- return GetPos(node[u]) + Size(node[u]->lef);
- }
- int GetPos2(Tr *root)
- {
- if(root->pai == NULL) return 0;
- if(root->pai->lef == root) return GetPos2(root->pai);
- else return GetPos2(root->pai) + Size(root->pai->lef) + 1;
- }
- int GetPos2(int u)
- {
- return GetPos2(node2[u]) + Size(node2[u]->lef);
- }
- int GetNxt(Tr *root)
- {
- if(GetMin(root->lef) < NMAX) return GetNxt(root->lef);
- if(root->val < NMAX) return Size(root->lef);
- return GetNxt(root->rig) + Size(root->lef) + 1;
- }
- int GetNxt(Tr **root, int u)
- {
- Tr *before, *after, *l, *m, *r, *aux;
- int p = GetPos2(u + NMAX);
- Split(*root, p, &before, &after, 2);
- p = GetNxt(after);
- Split(after, p, &l, &aux, 2);
- Split(aux, 1, &m, &r, 2);
- int x = m->val;
- *root = Merge(Merge(Merge(before, l, 2), m, 2), r, 2);
- return x;
- }
- int Solv(Tr *root, int idx)
- {
- Tr *l, *r, *aux;
- Split(root, idx, &l, &aux, 1);
- Split(aux, 1, &l, &r, 1);
- return l->val;
- }
- int main()
- {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- int t, n, op, u, v, val, l, r, p, i, j;
- vector< int > resp;
- Treap *treapId, *treapVal, *treapInOut;
- srand(time(NULL));
- treapId = NULL;
- treapVal = NULL;
- treapInOut = NULL;
- cin >> val >> n;
- Add(&treapId, &treapVal, &treapInOut, 0, 0, 0);
- Add(&treapId, &treapVal, &treapInOut, 0, 0, val);
- while(n--)
- {
- cin >> op;
- if(op == 1)
- {
- cin >> u >> val;
- v = GetNxt(&treapInOut, u);
- Add(&treapId, &treapVal, &treapInOut, GetPos(v), GetPos2(u + NMAX), val);
- }
- if(op == 2)
- {
- cin >> l >> r;
- l--;
- r--;
- Invert(&treapVal, l, r);
- }
- if(op == 3)
- {
- cin >> u;
- resp.push_back(Solv(treapVal, GetPos(u)));
- }
- }
- for(auto cur : resp) cout << cur << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement