Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sstream>
- #include <cmath>
- #include <algorithm>
- #include <string>
- #include <string.h>
- #include <cstdio>
- #include <vector>
- #include <map>
- #include <set>
- #include <cstring>
- #include <queue>
- #include <bitset>
- #include <queue>
- #include <unordered_map>
- using namespace std;
- struct node
- {
- int l, r, p, x;
- };
- int uk = 0;
- int last = 0;
- node d[11000001];
- int n;
- void update(int v) {
- d[v].p = d[d[v].l].p + d[d[v].r].p + 1;
- }
- int clone(int v) {
- uk++;
- int a = uk;
- d[a] = d[v];
- return a;
- }
- void split(int v, int x, int &l, int &r) {
- if (v == 0) {
- l = 0; r = 0;
- return;
- }
- if (x == 0) {
- l = 0;
- r = v;
- return;
- }
- int a = clone(v);
- if (x >= d[d[v].l].p + 1) {
- split(d[a].r, x - d[d[v].l].p - 1, d[a].r, r);
- l = a;
- update(a);
- } else {
- split(d[a].l, x, l, d[a].l);
- r = a;
- update(a);
- }
- }
- int goodrand() {
- return (rand() << 15) + rand();
- }
- int merge(int l, int r) {
- if (l == 0) {
- return r;
- }
- if (r == 0) {
- return l;
- }
- if (goodrand() % (d[l].p + d[r].p) < d[l].p) {
- int a = clone(l);
- d[a].r = merge(d[a].r, r);
- update(a);
- return a;
- } else {
- int a = clone(r);
- d[a].l = merge(l, d[a].l);
- update(a);
- return a;
- }
- }
- int kk = 0;
- void vivedi(int v) {
- if (v == 0) {
- return;
- }
- vivedi(d[v].l);
- printf("%d\n", d[v].x);
- vivedi(d[v].r);
- }
- int go(int v, int t) {
- if (v == 0) {
- return 0;
- }
- int a = clone(v);
- d[a].x = last + t + d[d[a].l].p + 1;
- d[a].l = go(d[a].l, t);
- d[a].r = go(d[a].r, t + d[d[a].l].p + 1);
- return a;
- }
- int gh = 0;
- node d1[200002];
- int perestr(int v) {
- if (v == 0) {
- return 0;
- }
- gh++;
- int a = gh;
- d1[a] = d[v];
- d1[a].l = perestr(d[v].l);
- d1[a].r = perestr(d[v].r);
- return a;
- }
- int main() {
- int q;
- cin >> n >> q;
- // n = 200000;
- // q = 200000;
- int root = 0;
- uk = n;
- for (int i = 0; i < n; i++) {
- int a = i + 1;
- d[i + 1].p = 1;
- d[i + 1].x = a;
- root = merge(root, i + 1);
- }
- last = n;
- for (int i1 = 0; i1 < q; i1++) {
- if (i1 % 10000 == 1) {
- gh = 0;
- root = perestr(root);
- uk = n;
- for (int j = 1; j <= n; j++) {
- d[j] = d1[j];
- }
- }
- string s;
- cin >> s;
- if (s == "f") {
- int i, j, k;
- scanf("%d %d %d", &i, &j, &k);
- if (i == j) {
- continue;
- }
- if ((i > j || abs(i - j) >= k)) {
- int root1 = clone(root);
- int c, d1;
- split(root, i - 1, c, d1);
- int g, h;
- split(d1, k, g, h);
- int c1, d11;
- split(root1, j - 1, c1, d11);
- int g1, h1;
- split(d11, k, g1, h1);
- root1 = merge(c1, g);
- root1 = merge(root1, h1);
- root = clone(root1);
- } else {
- //cout << "hh" << endl;
- int root1 = clone(root);
- // vivedi(root);
- // cout << "opa" << endl;
- int a, b, a1, b1;
- split(root, i - 1, a, b);
- int root2 = clone(b);
- int c, dd;
- split(root2, j - i, c, dd);
- split(root1, j - 1, a1, b1);
- int e, f;
- split(b1, k, e, f);
- root1 = a1;
- int l = k / (j - i);
- int g = k - l * (j - i);
- int h = clone(c);
- int t, p;
- split(h, g, t, p);
- vector<int> v;
- while (l > 0) {
- v.push_back((l & 1));
- l = (l >> 1);
- }
- reverse(v.begin(), v.end());
- int cc1 = 0;
- int v1 = (int)v.size();
- for (int j1 = 0; j1 < v1; j1++) {
- if (v[j1] == 1) {
- cc1 = merge(cc1, clone(c));
- }
- if (j1 != v1 - 1) {
- cc1 = merge(cc1, cc1);
- }
- }
- root1 = merge(root1, cc1);
- root1 = merge(root1, t);
- root1 = merge(root1, f);
- root = clone(root1);
- }
- continue;
- }
- if (s == "x") {
- int a, b;
- scanf("%d %d", &a, &b);
- int c, d1;
- split(root, a - 1, c, d1);
- int e, f;
- split(d1, b - a + 1, e, f);
- e = go(e, 0);
- last += b - a + 1;
- root = merge(c, e);
- root = merge(root, f);
- continue;
- }
- int i, j, k;
- scanf("%d %d %d", &i, &j, &k);
- if (i == j) {
- continue;
- }
- swap(i, j);
- if ((i < j || abs(i - j) >= k)) {
- i = i - k + 1;
- j = j - k + 1;
- int root1 = clone(root);
- int c, d1;
- split(root, i - 1, c, d1);
- int g, h;
- split(d1, k, g, h);
- int c1, d11;
- split(root1, j - 1, c1, d11);
- int g1, h1;
- split(d11, k, g1, h1);
- root1 = merge(c1, g);
- root1 = merge(root1, h1);
- root = clone(root1);
- } else {
- int root1 = clone(root);
- int a, b, a1, b1;
- split(root, i, a, b);
- int root2 = clone(a);
- int c, dd;
- split(root2, j, dd, c);
- split(root1, j, a1, b1);
- int e, f;
- split(a1, j - k, e, f);
- root1 = b1;
- int l = k / (i - j);
- int g = k - l * (i - j);
- int h = clone(c);
- int t, p;
- split(h, i - j - g, t, p);
- vector<int> v;
- while (l > 0) {
- v.push_back((l & 1));
- l = (l >> 1);
- }
- reverse(v.begin(), v.end());
- int cc1 = 0;
- int v1 = (int)v.size();
- for (int j1 = 0; j1 < v1; j1++) {
- if (v[j1] == 1) {
- cc1 = merge(cc1, clone(c));
- }
- if (j1 != v1 - 1) {
- cc1 = merge(cc1, cc1);
- }
- }
- root1 = merge(cc1, root1);
- root1 = merge(p, root1);
- root1 = merge(e, root1);
- root = clone(root1);
- }
- }
- vivedi(root);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement