算了下空间好像并没有超,把 N 置成 20001 就彩虹了
#include<bits/stdc++.h>
using namespace std;
#define reg register
#define ll long long
extern "C" {
namespace io {
#define BUFS 100001
static char in[BUFS], *p = in, *pp = in;
#define gc() (p == pp && (pp = (p = in) + fread(in, 1, BUFS, stdin), p == pp) ? EOF : *p++)
inline int read() {
reg int x = 0; reg char ch, f = 0;
while (!isdigit(ch = gc())) f|= ch == '-';
while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
return f ? -x :x;
}
}
}
#define rd io :: read
const int N = 200001;
int n, m;
struct Node {
ll siz; Node *ls, *rs;
Node();
} nds[N << 5], *null = nds, *pl[N << 5], **ptr = pl, *bac[N << 5], **_ptr = bac, *root[N];
Node :: Node() : ls(null), rs(null) {};
#define newNode() (_ptr != bac ? *_ptr-- : *++ptr)
inline void init() {for (reg int i = 0; i < N << 5; ++i) pl[i] = nds + i;}
inline void recyc(Node *x) {*++_ptr = x, x -> ls = x -> rs = null;}
void modify(Node *&cur, int l, int r, int p, int v) {
if (cur == null) cur = newNode();
cur -> siz += v;
if (l == r) return ;
int mid = l + r >> 1;
p <= mid && (modify(cur -> ls, l, mid, p, v), 0),
mid < p && (modify(cur -> rs, mid + 1, r, p, v), 0);
}
ll query(Node *cur, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return cur -> siz;
int mid = l + r >> 1, sm = 0;
ql <= mid && (sm += query(cur -> ls, l, mid, ql, qr)),
mid < qr && (sm += query(cur -> rs, mid + 1, r, ql, qr));
return sm;
}
int kth(Node *cur, int l, int r, int k) {
if (l == r) return l;
int mid = l + r >> 1;
return cur -> ls -> siz >= k ? kth(cur -> ls, l, mid, k) : kth(cur -> rs, mid + 1, r, k - cur -> ls -> siz);
}
Node *merge(Node *x, Node *y) {
if (x == null || y == null) return x == null ? y : x;
x -> siz += y -> siz;
x -> ls = merge(x -> ls, y -> ls), x -> rs = merge(x -> rs, y -> rs);
recyc(y);
return x;
}
void split(Node *x, Node *&y, ll k) {
if (x == null) return ;
y = newNode();
ll v = x -> ls -> siz;
k > v ? split(x -> rs, y -> rs, k - v) : swap(x -> rs, y -> rs);
k < v && (split(x -> ls, y -> ls, k), 0);
y -> siz = x -> siz - k;
x -> siz = k;
}
int main() {
freopen("1.in", "r", stdin);
int tot = 1;
init();
n = rd(), m = rd();
for (reg int i = 1; i <= n; ++i) root[i] = null;
for (reg int i = 1, x; i <= n; ++i)
x = rd(), modify(root[1], 1, n, i, x);
for (reg int i = 1; i <= m; ++i) {
int op = rd(), x, y, z; ll k1, k2;
Node *tmp;
switch(op) {
case 0 :
x = rd(), y = rd(), z = rd();
k1 = query(root[x], 1, n, 1, z), k2 = query(root[x], 1, n, y, z);
split(root[x], root[++tot], k1 - k2),
split(root[tot], tmp, k2);
root[x] = merge(root[x], tmp);
break;
case 1 :
x = rd(), y = rd();
root[x] = merge(root[x], root[y]);
break;
case 2 :
x = rd(), y = rd(), z = rd();
modify(root[x], 1, n, z, y);
break;
case 3 :
x = rd(), y = rd(), z = rd();
printf("%lld\n", query(root[x], 1, n, y, z), 0);
break;
case 4 :
x = rd(), y = rd();
if (root[x] -> siz < y) {puts("-1"); continue;}
printf("%d\n", kth(root[x], 1, n, y));
break;
}
}
return 0;
}