1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| #include <bits/stdc++.h> #define rep(i, x, y) for (int i = x; i <= y; i++) #define mid ((l + r) >> 1) using namespace std;
typedef long long ll; const int N = 2e5 + 10, M = N * 60; int n, m, a[N], idx, id; int rt[N], ls[M], rs[M]; ll sz[M];
void upd(int x) { sz[x] = sz[ls[x]] + sz[rs[x]]; }
void build(int &x, int l, int r) { if (!x) x = ++idx; if (l == r) { scanf("%lld", &sz[x]); return; } build(ls[x], l, mid), build(rs[x], mid + 1, r); upd(x); }
void insert(int &x, int l, int r, int p, int v) { if (!x) x = ++idx; if (l == r) { sz[x] += v; return; } p <= mid ? insert(ls[x], l, mid, p, v) : insert(rs[x], mid + 1, r, p, v); upd(x); }
ll query(int x, int l, int r, int lx, int rx) { if (lx <= l && r <= rx) { return sz[x]; } ll ret = 0; if (lx <= mid) ret = query(ls[x], l, mid, lx, rx); if (rx > mid) ret += query(rs[x], mid + 1, r, lx, rx); return ret; }
void merge(int &x, int y, int l, int r) { if (!x || !y) { x |= y; return; } if (l == r) { sz[x] += sz[y]; return; } merge(ls[x], ls[y], l, mid); merge(rs[x], rs[y], mid + 1, r); upd(x); }
void split(int &x, int &y, int l, int r, int lx, int rx) { if (!y) return; if (lx <= l && r <= rx) { x = y, y = 0; return; } if (!x) x = ++idx; if (lx <= mid) split(ls[x], ls[y], l, mid, lx, rx); if (rx > mid) split(rs[x], rs[y], mid + 1, r, lx, rx); upd(y); upd(x); }
int ask(int x, int l, int r, int k) { if (k <= 0 || sz[x] < k) return -1; if (l == r) return l; if (k <= sz[ls[x]]) return ask(ls[x], l, mid, k); else return ask(rs[x], mid + 1, r, k - sz[ls[x]]); }
int main() { cin >> n >> m; ++id; build(rt[id], 1, n); while (m--) { int op, x, y, z; scanf("%d%d", &op, &x); if (op == 1 || op == 4) scanf("%d", &y); else scanf("%d%d", &y, &z); if (!op) { ++id; split(rt[id], rt[x], 1, n, y, z); } else if (op == 1) { merge(rt[x], rt[y], 1, n); } else if (op == 2) { insert(rt[x], 1, n, z, y); } else if (op == 3) { printf("%lld\n", query(rt[x], 1, n, y, z)); } else { printf("%d\n", ask(rt[x], 1, n, y)); } } return 0; }
|