萌新刚学OI,splay求捉虫
查看原帖
萌新刚学OI,splay求捉虫
519384
Link_Cut_Y楼主2022/7/28 21:51

原程序

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 50010, INF = 0x3f3f3f3f;

int n, m, root, idx;
struct Splay {
	int s[2], p, v;
	int rev, maxn, size, add;
	void init(int _p, int _v) {
		p = _p, v = _v;
		size = 1, rev = 0, maxn = -2e9, add = 0;
	}
}tr[N];
#define ls tr[x].s[0]
#define rs tr[x].s[1]
void pushup(int x) {
	tr[x].size = tr[ls].size + tr[rs].size + 1;
	tr[x].maxn = max(tr[x].v, max(tr[ls].maxn, tr[rs].maxn));
}
void pushdown(int x) {
	if (tr[x].rev) {
		swap(ls, rs);
		if (ls) tr[ls].rev ^= 1;
		if (rs) tr[rs].rev ^= 1;
		tr[x].rev ^= 1;
	}
	if (tr[x].add) {
		if (ls) {
			tr[ls].maxn += tr[x].add;
			tr[ls].v += tr[x].add;
			tr[ls].add += tr[x].add;
		}
		if (rs) {
			tr[rs].maxn += tr[x].add;
			tr[rs].v += tr[x].add;
			tr[rs].add += tr[x].add;
		}
		tr[x].add = 0;
	}
}
void rotate(int x) {
	int y = tr[x].p, z = tr[y].p;
	int k = tr[y].s[1] == x;
	if (z) tr[z].s[tr[z].s[1] == y] = x; tr[x].p = z;
	tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y;
	tr[x].s[k ^ 1] = y, tr[y].p = x;
	pushup(y), pushup(x);
}
void splay(int x, int k) {
	while (tr[x].p != k) {
		int y = tr[x].p, z = tr[y].p;
		if (z != k) rotate(((tr[z].s[1] == y) ^ (tr[y].s[1] == x)) ? y : x);
		rotate(x);
	}
	if (!k) root = x;
}
void insert(int v) {
	int u = root;
	while (tr[u].s[1]) u = tr[u].s[1];
	tr[u].s[1] = ++ idx, tr[idx].init(u, v);
	tr[idx].maxn = -INF;
	splay(idx, 0);
}
int find(int x) {
	int u = root;
	while (true) {
		pushdown(u);
		if (tr[tr[u].s[0]].size >= x) u = tr[u].s[0];
		else if (tr[tr[u].s[0]].size + 1 == x) return u;
		else x -= tr[tr[u].s[0]].size + 1, u = tr[u].s[1];
	}
	return -1;
}
void reverse(int l, int r) {
	l = find(l), r = find(r + 2);
	splay(l, 0), splay(r, l);
	tr[tr[r].s[0]].rev ^= 1;
}
void add(int l, int r, int v) {
	l = find(l), r = find(r + 2);
	splay(l, 0), splay(r, l);
	tr[tr[r].s[0]].add += v, tr[tr[r].s[0]].v += v, tr[tr[r].s[0]].maxn += v;
	pushup(r), pushup(l);
}
int get_max(int l, int r) {
	l = find(l), r = find(r + 2);
	splay(l, 0), splay(r, l);
	return tr[tr[r].s[0]].maxn;
}
void dfs(int u) {
	if (tr[u].s[0]) dfs(tr[u].s[0]);
	cout << tr[u].maxn << ' ';
	if (tr[u].s[1]) dfs(tr[u].s[1]);
}

int main()
{
	// freopen("data.out", "r", stdin);
	// freopen("my.out", "w", stdout);
	scanf("%d%d", &n, &m);
	insert(-2e9);
	for (int i = 1; i <= n; i ++ )
		insert(0);
	insert(-2e9);
//	dfs(root);
	
	while (m -- ) {
		int op, l, r, v;
		scanf("%d%d%d", &op, &l, &r);
		if (op == 1) {
			scanf("%d", &v);
			add(l, r, v);
		}
		else if (op == 2) {
			reverse(l, r);
		}
		else {
			printf("%d\n", get_max(l, r));
		}
	}
	return 0;
}

标程:不放了,题解复制的。

生成数据:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <ctime>

using namespace std;

int main()
{
	freopen("data.out", "w", stdout);
	srand(time(NULL));
	int n = rand() % 50000 + 1, m = rand() % 100000 + 1;
	cout << n << ' ' << m << endl;
	for (int i = 1; i <= m; i ++ ) {
		int op = rand() % 3 + 1;
		int l = rand() % n + 1, r = rand() % n + 1;
		if (l > r) swap(l, r);
		if (op == 1) {
			int v = rand() % 100000;
			cout << op << ' ' << l << ' ' << r << ' ' << v << endl;
		}
		if (op == 2) {
			cout << op << ' ' << l << ' ' << r << endl;
		}
		if (op == 3)
			cout << op << ' ' << l << ' ' << r << endl;
	}
	return 0;
} 

对拍:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	while (true) {
		system("DataMaker.exe");
		system("序列终结者splay.exe");
		system("std.exe");
		system("fc my.out std.out");
	}
	return 0;
}
2022/7/28 21:51
加载中...