fhq_treap样例过了但交上去爆0
查看原帖
fhq_treap样例过了但交上去爆0
162196
伟大的王夫子楼主2020/8/14 17:46
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef long long ll;
struct fhq_treap {
	int ls, rs, dat, size, val;
	ll sum, add;
} tr[N];
int root, n, m, tot;
int New(int val) {
	tr[++tot].val = val;
	tr[tot].sum = val;
	tr[tot].dat = rand();
	tr[tot].size = 1;
	return tot;
}
inline void spreadadd(int x, ll y) {
	if (!x || !y) return;
	tr[x].add += y, tr[x].sum += y, tr[x].val += y;
}
inline void spread(int x) {
	spreadadd(tr[x].ls, tr[x].add);
	spreadadd(tr[x].rs, tr[x].add);
	tr[x].add = 0;
}
inline void update(int x) {
	tr[x].sum = tr[tr[x].ls].sum + tr[tr[x].rs].sum + tr[x].val;
	tr[x].size = tr[tr[x].ls].size + tr[tr[x].rs].size + 1;
}
int merge(int x, int y) {
	if (!x || !y) return x + y;
	if (tr[x].dat < tr[y].dat) {
		spread(x);
		tr[x].rs = merge(tr[x].rs, y);
		update(x);
		return x;
	} else {
		spread(y);
		tr[y].ls = merge(x, tr[y].ls);
		update(y);
		return y;
	}
}
void split(int now, int k, int &x, int &y) {
	if (!now) {
		x = y = 0;
		return;
	}
	spread(now);
	if (tr[tr[now].ls].size < k)
		x = now, split(tr[now].rs, k - tr[tr[now].ls].size - 1, tr[now].rs, y);
	else
		y = now, split(tr[now].ls, k, x, tr[now].ls);
	update(now);
}
void dfs(int now) {
	if (!now) return;
	dfs(tr[now].ls);
	printf("%d ", tr[now].val);
	dfs(tr[now].rs);
}
int main() {
	cin >> n >> m;
	for (register int i = 1; i <= n; ++i) {
		int x;
		scanf("%d", &x);
		root = merge(root, New(x));
	}
	//dfs(root);
	while (m--) {
		int op, l, r, d;
		scanf("%d%d%d", &op, &l, &r);
		if (op == 1) {
			int a, b, c;
			split(root, l - 1, a, b);
			split(b, r - l + 1, b, c);
			scanf("%d", &d);
			spreadadd(b, d);
			root = merge(a, merge(b, c));
		} else {
			int a, b, c;
			split(root, l - 1, a, b);
			//dfs(a), puts(""), dfs(b);
			split(b, r - l + 1, b, c);
			//cout << c << endl;
			printf("%lld\n", tr[b].sum);
			root = merge(a, merge(b, c));
		}
	}
}
2020/8/14 17:46
加载中...