关于线段树分裂,为何莫名其妙MLE?
查看原帖
关于线段树分裂,为何莫名其妙MLE?
75765
Starlight237楼主2020/9/18 21:16

算了下空间好像并没有超,把 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;
}
2020/9/18 21:16
加载中...