总览
- 长达146km的代码
- 长达134km的代码
- 长达88km的代码
- 这个是个 0
- 长达124cm的代码
- 长达126km的代码
- 长达93mm的代码
- 长达66um的代码
替罪羊
| #include <algorithm> |
| #include <iostream> |
| |
| using namespace std; |
| |
| const int MaxN = 4e5 + 10; |
| const double eps = 0.75; |
| |
| int d[MaxN], l[MaxN], r[MaxN], cnt[MaxN], sum[MaxN], sz[MaxN], a[MaxN], tot, n, root, len; |
| |
| void update(int x) { |
| sum[x] = sum[l[x]] + sum[r[x]] + cnt[x]; |
| sz[x] = sz[l[x]] + sz[r[x]] + 1; |
| } |
| |
| bool Check(int x) { |
| return cnt[x] && 1.0 * max(sz[l[x]], sz[r[x]]) > eps * sz[x]; |
| } |
| |
| void dfs(int x) { |
| if (!x) { |
| return; |
| } |
| dfs(l[x]); |
| cnt[x] && (a[++len] = x); |
| dfs(r[x]); |
| } |
| |
| int build(int pl, int pr) { |
| if (pl > pr) { |
| return 0; |
| } |
| int mid = (pl + pr) >> 1; |
| l[a[mid]] = build(pl, mid - 1); |
| r[a[mid]] = build(mid + 1, pr); |
| update(a[mid]); |
| return a[mid]; |
| } |
| |
| int G(int k) { |
| len = 0; |
| dfs(k); |
| return k = build(1, len); |
| } |
| |
| void insert(int &k, int x) { |
| if (!k) { |
| k = ++tot; |
| (!root) && (root = tot); |
| d[tot] = x, l[tot] = r[tot] = 0, sum[tot] = cnt[tot] = sz[tot] = 1; |
| return; |
| } |
| if (d[k] == x) { |
| cnt[k]++; |
| } else if (d[k] < x) { |
| insert(r[k], x); |
| } else { |
| insert(l[k], x); |
| } |
| update(k); |
| if (Check(k)) { |
| k = G(k); |
| } |
| } |
| |
| void delet(int &k, int x) { |
| if (!k) { |
| return; |
| } |
| if (d[k] == x) { |
| cnt[k] && (cnt[k]--); |
| } else if (d[k] < x) { |
| delet(r[k], x); |
| } else { |
| delet(l[k], x); |
| } |
| update(k); |
| if (Check(k)) { |
| k = G(k); |
| } |
| } |
| |
| int At(int k, int x) { |
| if (!k) { |
| return 0; |
| } |
| if (sum[l[k]] < x && x <= sum[l[k]] + cnt[k]) { |
| return d[k]; |
| } else if (sum[l[k]] + cnt[k] < x) { |
| return At(r[k], x - sum[l[k]] - cnt[k]); |
| } |
| return At(l[k], x); |
| } |
| |
| int upbd(int k, int x) { |
| if (!k) { |
| return 1; |
| } |
| if (d[k] == x && cnt[k]) { |
| return sum[l[k]] + cnt[k] + 1; |
| } else if (x < d[k]) { |
| return upbd(l[k], x); |
| } |
| return upbd(r[k], x) + sum[l[k]] + cnt[k]; |
| } |
| |
| int upgrt(int k, int x) { |
| if (!k) { |
| return 0; |
| } |
| if (d[k] == x && cnt[k]) { |
| return sum[l[k]]; |
| } else if (d[k] < x) { |
| return upgrt(r[k], x) + sum[l[k]] + cnt[k]; |
| } |
| return upgrt(l[k], x); |
| } |
| |
| int p(int x) { |
| return At(root, upgrt(root, x)); |
| } |
| |
| int h(int x) { |
| return At(root, upbd(root, x)); |
| } |
| |
| int main() { |
| cin >> n; |
| for (int op, x; n; n--) { |
| cin >> op >> x; |
| if (op == 1) { |
| insert(root, x); |
| } else if (op == 2) { |
| delet(root, x); |
| } else if (op == 3) { |
| cout << upgrt(root, x) + 1 << '\n'; |
| } else if (op == 4) { |
| cout << At(root, x) << '\n'; |
| } else if (op == 5) { |
| cout << p(x) << '\n'; |
| } else { |
| cout << h(x) << '\n'; |
| } |
| } |
| return 0; |
| } |
旋转Treap
| #include <ctime> |
| #include <iostream> |
| #include <random> |
| |
| using namespace std; |
| |
| const int MaxN = 1e5 + 10; |
| |
| struct Node { |
| int d, v, l, r, sum, cnt; |
| } w[MaxN]; |
| |
| int n, root, tot; |
| |
| void update(int x) { |
| w[x].sum = w[w[x].l].sum + w[w[x].r].sum + w[x].cnt; |
| } |
| |
| void left(int &k) { |
| int p = w[k].l; |
| w[k].l = w[p].r, w[p].r = k, k = p; |
| update(w[k].r), update(k); |
| } |
| |
| void right(int &k) { |
| int p = w[k].r; |
| w[k].r = w[p].l, w[p].l = k, k = p; |
| update(w[k].l), update(k); |
| } |
| |
| void insert(int &k, int x) { |
| if (!k) { |
| k = ++tot; |
| w[k] = {x, rand(), 0, 0, 1, 1}; |
| return; |
| } |
| if (w[k].d == x) { |
| w[k].cnt++; |
| } else if (w[k].d < x) { |
| insert(w[k].r, x); |
| if (w[w[k].r].v < w[k].v) { |
| right(k); |
| } |
| } else { |
| insert(w[k].l, x); |
| if (w[w[k].l].v < w[k].v) { |
| left(k); |
| } |
| } |
| update(k); |
| } |
| |
| void delet(int &k, int x) { |
| if (!k) { |
| return; |
| } |
| if (w[k].d == x) { |
| if (w[k].cnt) { |
| w[k].cnt--, update(k); |
| } else if (w[k].l || w[k].r) { |
| if (!w[k].r || w[w[k].l].d > w[w[k].r].d) { |
| left(k), delet(w[k].l, x); |
| } else { |
| right(k), delet(w[k].r, x); |
| } |
| update(k); |
| } else { |
| k = 0; |
| } |
| } |
| if (w[k].d < x) { |
| delet(w[k].r, x); |
| } else { |
| delet(w[k].l, x); |
| } |
| update(k); |
| } |
| |
| int upbd(int k, int x) { |
| if (!k) { |
| return 1; |
| } |
| if (w[k].d == x) { |
| return w[w[k].l].sum + w[k].cnt + 1; |
| } else if (w[k].d < x) { |
| return upbd(w[k].r, x) + w[w[k].l].sum + w[k].cnt; |
| } |
| return upbd(w[k].l, x); |
| } |
| int upgrt(int k, int x) { |
| if (!k) { |
| return 0; |
| } |
| if (w[k].d == x) { |
| return w[w[k].l].sum; |
| } else if (x < w[k].d) { |
| return upgrt(w[k].l, x); |
| } |
| return upgrt(w[k].r, x) + w[w[k].l].sum + w[k].cnt; |
| } |
| |
| int At(int k, int x) { |
| if (!k) { |
| return 0; |
| } |
| if (w[w[k].l].sum < x && x <= w[w[k].l].sum + w[k].cnt) { |
| return w[k].d; |
| } else if (w[w[k].l].sum + w[k].cnt < x) { |
| return At(w[k].r, x - w[w[k].l].sum - w[k].cnt); |
| } |
| return At(w[k].l, x); |
| } |
| |
| int main() { |
| srand(time(NULL)); |
| cin >> n; |
| for (int op, x; n; n--) { |
| cin >> op >> x; |
| if (op == 1) { |
| insert(root, x); |
| } else if (op == 2) { |
| delet(root, x); |
| } else if (op == 3) { |
| cout << upgrt(root, x) + 1 << '\n'; |
| } else if (op == 4) { |
| cout << At(root, x) << '\n'; |
| } else if (op == 5) { |
| cout << At(root, upgrt(root, x)) << '\n'; |
| } else { |
| cout << At(root, upbd(root, x)) << '\n'; |
| } |
| } |
| return 0; |
| } |

FHQ
| #include <iostream> |
| #include <ctime> |
| |
| using namespace std; |
| |
| const int MaxN = 2e6 + 10; |
| |
| struct S { |
| int x, v, ls, rs, sum; |
| } a[MaxN]; |
| |
| int rt, tot, t, n, ans; |
| |
| int update(int k) { |
| return a[k].sum = k ? a[a[k].ls].sum + a[a[k].rs].sum + 1 : 0, k; |
| } |
| |
| void split(int k, int v, int &x, int &y) { |
| if (!k) return; |
| int l = a[k].ls, r = a[k].rs; |
| ((a[k].x <= v) ? (split(r, v, a[k].rs = 0, y), x) : (split(l, v, x, a[k].ls = 0), y)) = k; |
| update(k); |
| } |
| |
| int merge(int x, int y) { |
| if (!x || !y) return x | y; |
| return update((a[x].v <= a[y].v) ? (a[x].rs = merge(a[x].rs, y), x) : (a[y].ls = merge(x, a[y].ls), y)); |
| } |
| |
| void insert(int v, int x = 0, int y = 0) { |
| split(rt, v, x, y); |
| a[++tot] = {v, rand(), 0, 0, 1}; |
| rt = merge(merge(x, tot), y); |
| } |
| |
| void delet(int &k, int x) { |
| if (a[k].x == x) { |
| k = merge(a[k].ls, a[k].rs); |
| } else { |
| a[k].x <= x ? delet(a[k].rs, x) : delet(a[k].ls, x); |
| update(k); |
| } |
| } |
| |
| int upgrt(int k, int x) { |
| if (!k) return 0; |
| if (a[k].x >= x) { |
| return upgrt(a[k].ls, x); |
| } |
| return upgrt(a[k].rs, x) + a[a[k].ls].sum + 1; |
| } |
| |
| int shit2(int k, int x) { |
| if (!k) return 0; |
| if (x == a[a[k].ls].sum + 1) { |
| return a[k].x; |
| } else if (a[a[k].ls].sum + 1 < x) { |
| return shit2(a[k].rs, x - a[a[k].ls].sum - 1); |
| } |
| return shit2(a[k].ls, x); |
| } |
| |
| int main() { |
| ios::sync_with_stdio(0), cin.tie(0); |
| srand(time(NULL)); |
| cin >> n >> t; |
| for (int i = 1, x; i <= n; i++) { |
| cin >> x, insert(x); |
| } |
| for (int op, x, lst = 0; t; t--) { |
| cin >> op >> x, x ^= lst; |
| if (op == 1) { |
| insert(x); |
| } else if (op == 2) { |
| delet(rt, x); |
| } else if (op == 3) { |
| ans ^= (lst = upgrt(rt, x) + 1); |
| } else if (op == 4) { |
| ans ^= (lst = shit2(rt, x)); |
| } else if (op == 5) { |
| ans ^= (lst = shit2(rt, upgrt(rt, x))); |
| } else { |
| ans ^= (lst = shit2(rt, upgrt(rt, x + 1) + 1)); |
| } |
| } |
| cout << ans << endl; |
| return 0; |
| } |
平板电视
| #include <ext/pb_ds/assoc_container.hpp> |
| |
| #include <ext/pb_ds/tree_policy.hpp> |
| #include <ext/pb_ds/hash_policy.hpp> |
| #include <ext/pb_ds/priority_queue.hpp> |
| using namespace std; |
| using namespace __gnu_pbds; |
| |
| typedef int pii; |
| |
| void tree_test() |
| { |
| tree<pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update> t,nt; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| void priority_queue_test() |
| { |
| |
| __gnu_pbds::priority_queue<pii,std::less<pii>,pairing_heap_tag> Q,nQ; |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| void hash_test() |
| { |
| gp_hash_table<string,int> mp; |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| int main() |
| { |
| tree_test(); |
| hash_test(); |
| priority_queue_test(); |
| } |
FHQ 进阶
| #include <iostream> |
| #include <ctime> |
| |
| using namespace std; |
| |
| const int MaxN = 2e5 + 10; |
| |
| struct tree { |
| struct S { |
| int w, v, l, r, sum, tag, fa; |
| char c; |
| } a[MaxN]; |
| |
| int tot, root; |
| bool vis[MaxN]; |
| |
| int update(int k) { |
| (a[k].l) && (a[a[k].l].fa = k), (a[k].r) && (a[a[k].r].fa = k); |
| a[k].fa = 0; |
| return (k) && (a[k].sum = a[a[k].l].sum + a[a[k].r].sum + 1, a[k].w = a[a[k].l].w | a[a[k].r].w | (1 << (a[k].c - 'a'))), k; |
| } |
| |
| void pd(int k) { |
| if (!a[k].tag) return; |
| swap(a[k].l, a[k].r); |
| a[a[k].l].tag ^= 1, a[a[k].r].tag ^= 1; |
| a[k].tag = 0; |
| } |
| |
| int split(int k, int v, int &x, int &y, int l = 0, int r = 0) { |
| if (!k) return x = y = 0; |
| pd(k), l = a[k].l, r = a[k].r; |
| ((a[l].sum + 1 <= v) ? (split(r, v - a[l].sum - 1, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k; |
| return update(k); |
| } |
| |
| int merge(int x, int y) { |
| if (!x || !y) return x | y; |
| return update((a[x].v < a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y)); |
| } |
| |
| void insert(int id, char c, int s = 0, int b = 0) { |
| split(root, id, s, b); |
| a[++tot] = {(1 << (c - 'a')), rand(), 0, 0, 1, 0, 0, c}; |
| root = merge(merge(s, tot), b), vis[tot] = 1; |
| } |
| |
| void erase(int id, int k = 0, int y = 0, int n = 0) { |
| split(root, id - 1, k, n); |
| split(n, 1, y, n); |
| vis[y] = 0; |
| root = merge(k, n); |
| } |
| |
| int query(int l, int r, int k = 0, int y = 0, int n = 0) { |
| split(root, r, k, n); |
| split(k, l - 1, k, y); |
| int res = a[y].w; |
| root = merge(merge(k, y), n); |
| return __builtin_popcount(res); |
| } |
| |
| void reverse(int l, int r, int k = 0, int y = 0, int n = 0) { |
| split(root, r, k, n); |
| split(k, l - 1, k, y); |
| a[y].tag ^= 1; |
| root = merge(merge(k, y), n); |
| } |
| |
| char At(int k, int x) { |
| if (!k) return 0; |
| pd(k); |
| if (a[a[k].l].sum + 1 < x) { |
| return At(a[k].r, x - a[a[k].l].sum - 1); |
| } else if (a[a[k].l].sum >= x) { |
| return At(a[k].l, x); |
| } |
| return a[k].c; |
| } |
| |
| bool DFS(int x) { |
| if (!x) return 1; |
| DFS(a[x].fa), pd(x); |
| return 1; |
| } |
| |
| int Gk(int k, bool flag = 1) { |
| if (!vis[k] || k == root) return 0; |
| (flag) && (DFS(k)); |
| return Gk(a[k].fa, 0) + flag * (a[a[k].l].sum + 1) + (a[a[k].fa].r == k) * (a[a[a[k].fa].l].sum + 1); |
| } |
| } tr; |
| |
| int n, m; |
| string s; |
| |
| int main() { |
| srand(time(NULL)); |
| cin >> n >> m >> s; |
| for (int i = 0; i < n; i++) { |
| tr.insert(i + 1, s[i]); |
| } |
| for (int x, y; m; m--) { |
| char op, c; |
| cin >> op >> x; |
| if (op == 'I') { |
| cin >> c; |
| tr.insert(x, c); |
| } else if (op == 'D') { |
| tr.erase(x); |
| } else if (op == 'R') { |
| cin >> y; |
| tr.reverse(x, y); |
| } else if (op == 'P') { |
| cout << tr.Gk(x) << endl; |
| } else if (op == 'T') { |
| cout << tr.At(tr.root, x) << endl; |
| } else { |
| cin >> y; |
| cout << tr.query(x, y) << endl; |
| } |
| } |
| return 0; |
| } |
splay
| #include <iostream> |
| |
| using namespace std; |
| |
| const int MaxN = 1e6 + 1e5 + 10; |
| |
| struct Tree { |
| struct Node { |
| int w, ch[2], fa, cnt, sum, tag, x; |
| } a[MaxN]; |
| |
| int tot, root, l, r; |
| |
| Node operator[](int k) { |
| return a[k]; |
| } |
| |
| void update(int k) { |
| a[k].sum = a[a[k].ch[0]].sum + a[a[k].ch[1]].sum + a[k].cnt; |
| } |
| |
| void pushdown(int k) { |
| if (a[k].tag) { |
| swap(a[k].ch[0], a[k].ch[1]); |
| a[a[k].ch[1]].tag ^= 1; |
| a[a[k].ch[0]].tag ^= 1; |
| a[k].tag = 0; |
| } |
| } |
| |
| void rotatr(int x) { |
| int y = a[x].fa, z = a[y].fa, k = a[y].ch[1] == x; |
| a[z].ch[y == a[z].ch[1]] = x, a[x].fa = z; |
| a[y].ch[k] = a[x].ch[k ^ 1], a[a[x].ch[k ^ 1]].fa = y; |
| a[x].ch[k ^ 1] = y, a[y].fa = x; |
| update(y); |
| } |
| |
| void splay(int x, int to = 0) { |
| for (int y, z; a[x].fa != to; y = a[x].fa, z = a[y].fa, (z != to) ? (((y == a[z].ch[1]) ^ (x == a[y].ch[1])) ? rotatr(x) : rotatr(y)) : void(), rotatr(x)) { |
| } |
| update(x), (to) || (root = x); |
| } |
| |
| int At(int x) { |
| int k = root; |
| if (!k) return k; |
| for (; (pushdown(k), a[k].ch[x > a[k].x]) && a[k].x != x; k = a[k].ch[x > a[k].x]) { |
| } |
| return splay(k), k; |
| } |
| |
| void insert(int x) { |
| int k = root, y = 0; |
| for (; k && a[k].x != x; y = k, k = a[k].ch[x > a[k].x]) { |
| } |
| (k) ? (a[k].cnt++) : (k = ++tot, a[k] = {x, {0, 0}, y, 1, 1, 0, x}, (y) && (a[y].ch[x > a[y].x] = k)); |
| splay(k); |
| } |
| |
| Tree() { |
| root = tot = 0; |
| a[0] = {0, {0, 0}, 0, 0, 0, 0}; |
| insert(-2e9), insert(2e9); |
| } |
| |
| int kth(int x) { |
| int k = root; |
| for (int tx, kll; (pushdown(k), k) && !(a[a[k].ch[0]].sum < x && x <= a[a[k].ch[0]].sum + a[k].cnt); kll = a[k].cnt + a[a[k].ch[0]].sum, tx = x, (kll < tx) && (x -= kll), k = a[k].ch[kll < tx]) { |
| } |
| return splay(k), k; |
| } |
| |
| int pn(int x, bool flag) { |
| At(x); |
| int k = root; |
| if (a[k].x > x && flag || a[k].x < x && !flag) return splay(k), k; |
| k = a[k].ch[flag]; |
| for (; a[k].ch[!flag]; k = a[k].ch[!flag]) { |
| } |
| return splay(k), k; |
| } |
| |
| void erase(int x) { |
| int pre = pn(x, 0), nxt = pn(x, 1); |
| splay(pre), splay(nxt, pre); |
| int k = a[nxt].ch[0]; |
| if (a[k].cnt > 1) { |
| a[k].cnt--; |
| splay(k); |
| } else { |
| a[nxt].ch[0] = 0; |
| splay(nxt); |
| } |
| } |
| |
| void reverse(int l, int r){ |
| l = kth(l), r = kth(r + 2); |
| splay(l), splay(r, l); |
| a[a[r].ch[0]].tag ^= 1; |
| } |
| |
| void DFS(int x) { |
| if (!x) return; |
| pushdown(x); |
| DFS(a[x].ch[0]); |
| if (a[x].x != -2e9 && a[x].x != 2e9) cout << a[x].x << " "; |
| DFS(a[x].ch[1]); |
| } |
| } tree; |
| |
| int n, m, ans; |
| |
| int main() { |
| ios::sync_with_stdio(0), cin.tie(0); |
| cin >> n >> m; |
| for (int i = 1; i <= n; i++) { |
| tree.insert(i); |
| } |
| for (int i = 1, l, r; i <= m; i++) { |
| cin >> l >> r; |
| tree.reverse(l, r); |
| } |
| tree.DFS(tree.root); |
| return 0; |
| } |
FHQ 进阶2
| #include <iostream> |
| #include <ctime> |
| |
| using namespace std; |
| |
| const int MaxN = 2e5 + 10; |
| |
| struct Tree { |
| struct Node { |
| int w, v, l, r, sum, tag; |
| } a[MaxN]; |
| |
| int root, tot; |
| |
| int update(int k) { |
| return a[k].sum = k ? a[a[k].l].sum + a[a[k].r].sum + 1 : 0, k; |
| } |
| |
| void pd(int k) { |
| a[a[k].l].w += a[k].tag, a[a[k].l].tag += a[k].tag; |
| a[a[k].r].w += a[k].tag, a[a[k].r].tag += a[k].tag; |
| a[k].tag = 0; |
| } |
| |
| void split(int k, int v, int &x, int &y, int l = 0, int r = 0) { |
| if (!k) return; |
| pd(k), l = a[k].l, r = a[k].r; |
| ((a[k].w <= v) ? (split(r, v, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k; |
| update(k); |
| } |
| |
| int merge(int x, int y) { |
| if (!x || !y) return x | y; |
| return update((a[x].v > a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y)); |
| } |
| |
| void insert(int w, int x = 0, int y = 0) { |
| a[++tot] = {w, rand(), 0, 0, 1, 0}; |
| split(root, w, x, y); |
| root = merge(merge(x, tot), y); |
| } |
| |
| void G(int w) { |
| a[root].w += w, a[root].tag += w; |
| } |
| |
| int At(int k, int x) { |
| if (!k) return -1; |
| pd(k); |
| if (a[a[k].r].sum + 1 < x) { |
| return At(a[k].l, x - a[a[k].r].sum - 1); |
| } else if (a[a[k].r].sum >= x) { |
| return At(a[k].r, x); |
| } |
| return a[k].w; |
| } |
| |
| int upgrt(int k, int x) { |
| if (!k) return 0; |
| pd(k); |
| if (x <= a[k].w) { |
| return upgrt(a[k].l, x); |
| } |
| return upgrt(a[k].r, x) + a[a[k].l].sum + 1; |
| } |
| } tr; |
| |
| int t, x, gz, ans; |
| char op; |
| |
| int main() { |
| srand(time(NULL)); |
| for (cin >> t >> gz; t; t--) { |
| cin >> op >> x; |
| if (op == 'I') { |
| if (x >= gz) { |
| tr.insert(x); |
| } |
| } else if (op == 'A') { |
| tr.G(x); |
| } else if (op == 'S') { |
| tr.G(-x); |
| int s = 0, b = 0; |
| tr.split(tr.root, gz - 1, s, b); |
| ans += tr.a[s].sum; |
| tr.root = b; |
| } else { |
| cout << tr.At(tr.root, x) << endl; |
| } |
| } |
| cout << ans << endl; |
| return 0; |
| } |
暴力加减如何呢?
文艺平衡树
只记录了一个题目的,用法太少了,所以我选择补一个完全没必要的
| #include <iostream> |
| #include <ctime> |
| |
| using namespace std; |
| |
| const int MaxN = 100010; |
| |
| struct S { |
| int v, l, r, sum, tag; |
| } a[MaxN]; |
| |
| int root, tot, n, m; |
| |
| int update(int k) { |
| return (k) && (a[k].sum = a[a[k].l].sum + a[a[k].r].sum + 1), k; |
| } |
| |
| void pd(int k) { |
| if (!a[k].tag) return; |
| swap(a[k].l, a[k].r); |
| a[a[k].l].tag ^= 1; |
| a[a[k].r].tag ^= 1; |
| a[k].tag = 0; |
| } |
| |
| int split(int k, int v, int &x, int &y, int l = 0, int r = 0) { |
| if (!k) return x = y = 0; |
| pd(k), l = a[k].l, r = a[k].r; |
| ((a[l].sum + 1 <= v) ? (split(r, v - 1 - a[l].sum, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k; |
| return update(k); |
| } |
| |
| int merge(int x, int y) { |
| if (!x || !y) return x | y; |
| return update((a[x].v < a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y)); |
| } |
| |
| void reverse(int l, int r) { |
| int tmp1 = 0, tmp2 = 0, tmp3 = 0; |
| split(root, r, tmp1, tmp3); |
| split(tmp1, l - 1, tmp1, tmp2); |
| a[tmp2].tag ^= 1; |
| root = merge(merge(tmp1, tmp2), tmp3); |
| } |
| |
| void DFS(int x) { |
| if (!x) return; |
| pd(x); |
| DFS(a[x].l); |
| cout << x << " "; |
| DFS(a[x].r); |
| } |
| |
| int main() { |
| srand(time(NULL)); |
| cin >> n >> m; |
| for (int i = 1; i <= n; i++) { |
| a[i] = {rand(), 0, 0, 1, 0}; |
| root = merge(root, i); |
| } |
| for (int i = 1, l, r; i <= m; i++) { |
| cin >> l >> r; |
| reverse(l, r); |
| } |
| DFS(root); |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步