社区讨论

关于fhq的疑问

学术版参与者 3已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@lo7kj4sl
此快照首次捕获于
2023/10/27 03:19
2 年前
此快照最后确认于
2023/10/27 03:19
2 年前
查看原帖
最近接触到使用mt19937生成随机数,然后用完以后发现编译一次一个结果,我知道fhq的随机化只会影响复杂度但是不会影响正确性,所以发帖求帮忙调错。
CPP
#include<bits/stdc++.h>
using namespace std;
inline int read() {
	int x = 0, w = 1;
	char ch = getchar();
	while ((ch < '0' || ch > '9') && ch != '-')
		ch = getchar();
	if (ch == '-') {
		w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * w;
}
void write(int x) {
	if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9)
		write(x / 10);
	putchar(x % 10 + 48);
}
const int N = 200005;
mt19937 rnd((unsigned long long)(new char) ^ (20060725 + 20060705));
stack<int>bin;
int n, m, tot, root;
struct Tag {
	int sam, rev;
	Tag operator +(const Tag &x)const {
		if (x.sam != N)
			return {x.sam, 0};
		if (sam != N)
			return {sam, 0};
		return {N, rev ^ x.rev};
	}
};
struct node {
	int l, r, siz, key, val, sum, lmax, rmax, maxx;
	Tag tag;
} tree[N << 1];
void pushup(int now) {
	node l = tree[tree[now].l], r = tree[tree[now].r];
	tree[now].siz = l.siz + r.siz + 1;
	tree[now].sum = l.sum + r.sum + tree[now].val;
	tree[now].lmax = max(l.maxx, max(l.sum + tree[now].val, l.sum + tree[now].val + r.lmax));
	tree[now].rmax = max(r.maxx, max(r.sum + tree[now].val, r.sum + tree[now].val + l.rmax));
	tree[now].maxx = max(l.maxx, max(r.maxx, max(l.rmax + tree[now].val, max(tree[now].val + r.lmax, l.rmax + tree[now].val + r.lmax))));
	tree[now].tag = {N, 0};
}
void apply(int now, Tag tag) {
	if (tag.sam != N) {
		tree[now].val = tag.sam;
		tree[now].sum = tree[now].siz * tag.sam;
		tree[now].lmax = tree[now].rmax = tree[now].maxx = (tag.sam > 0 ? tree[now].sum : tag.sam);
	}
	if (tag.rev) {
		swap(tree[now].l, tree[now].r);
		swap(tree[now].lmax, tree[now].rmax);
	}
}
void givetag(int now, Tag tag) {
	tree[now].tag = tree[now].tag + tag;
	apply(now, tag);
}
void pushdown(int now) {
	if (tree[now].tag.sam == N && tree[now].tag.rev == 0)
		return;
	givetag(tree[now].l, tree[now].tag);
	givetag(tree[now].r, tree[now].tag);
	tree[now].tag = {N, 0};
}
void recycle(int x) {
	bin.push(x);
	if (tree[x].l)
		recycle(tree[x].l);
	if (tree[x].r)
		recycle(tree[x].r);
}
int use() {
	if (!bin.empty()) {
		int x = bin.top();
		bin.pop();
		return x;
	}
	return ++tot;
}
void create(int &now, int x) {
	now = use();
	tree[now] = {0, 0, 1, (int)rnd(), x, x, x, x, x, {N, 0}};
}
void split(int now, int x, int &nowl, int &nowr) {
	if (!now) {
		nowl = nowr = 0;
		return ;
	}
	pushdown(now);
	if (tree[tree[now].l].siz + 1 <= x) {
		nowl = now;
		split(tree[now].r, x - tree[tree[now].l].siz - 1, tree[now].r, nowr);
	} else {
		nowr = now;
		split(tree[now].l, x, nowl, tree[now].l);
	}
	pushup(now);
}
int merge(int nowl, int nowr) {
	if (!nowl || !nowr)
		return nowl | nowr;
	pushdown(nowl);
	pushdown(nowr);
	if (tree[nowl].key < tree[nowr].key) {
		tree[nowl].r = merge(tree[nowl].r, nowr);
		pushup(nowl);
		return nowl;
	}
	tree[nowr].l = merge(nowl, tree[nowr].l);
	pushup(nowr);
	return nowr;
}
void INSERT() {
	int x = read(), cnt = read(), nowl, nowr, now;
	split(root, x, nowl, nowr);
	for (int i = 1; i <= cnt; i++) {
		
		create(now, read());
		nowl = merge(nowl, now);
	}
	root = merge(nowl, nowr);
}
void DELETE() {
	int x = read(), cnt = read(), nowl, nowmid, nowr;
	split(root, x - 1, nowl, nowr);
	split(nowr, cnt, nowmid, nowr);
	recycle(nowmid);
	root = merge(nowl, nowr);
}
void REVERSE() {
	int x = read(), cnt = read(), nowl, nowmid, nowr;
	split(root, x - 1, nowl, nowr);
	split(nowr, cnt, nowmid, nowr);
	givetag(nowmid, {N, 1});
	root = merge(merge(nowl, nowmid), nowr);
}
void MAKE_SAME() {
	int x = read(), cnt = read(), v = read(), nowl, nowmid, nowr;
	split(root, x - 1, nowl, nowr);
	split(nowr, cnt, nowmid, nowr);
	givetag(nowmid, {v, 0});
	root = merge(merge(nowl, nowmid), nowr);
}
void GET_SUM() {
	int x = read(), cnt = read(), nowl, nowmid, nowr;
	split(root, x - 1, nowl, nowr);
	split(nowr, cnt, nowmid, nowr);
//	write(tree[nowmid].sum);
	cout << tree[nowmid].sum;
	putchar('\n');
	root = merge(merge(nowl, nowmid), nowr);
}
void GET() {
	int x = read(), nowl, nowmid, nowr;
	split(root, x - 1, nowl, nowr);
	split(nowr, 1, nowmid, nowr);
	write(tree[nowmid].val);
	putchar('\n');
	root = merge(merge(nowl, nowmid), nowr);
}
void MAX_SUM() {
	int x = read(), cnt = read(), nowl, nowmid, nowr;
	split(root, x - 1, nowl, nowr);
	split(nowr, cnt, nowmid, nowr);
	write(tree[nowmid].maxx);
	putchar('\n');
	root = merge(merge(nowl, nowmid), nowr);
}
void Gets() {
	int cnt = tree[root].siz, nowl, nowmid, nowr;
	cout << cnt << endl;
	for (int i = 0; i < cnt; i++) {
		split(root,i, nowl, nowr);
		split(nowr, 1, nowmid, nowr);
		cout<<tree[nowmid].val<<" ";
		root = merge(merge(nowl, nowmid), nowr);
	}
	cout<<endl;
}
int main() {
	n = read();
	m = read();
	int now;
	for (int i = 1; i <= n; i++) {
		int x = read();
		create(now, x);
		root = merge(root, now);
	}
	for (int i = 1; i <= m; i++) {
		string opt;
		cin >> opt;
		if (opt == "INSERT")
			INSERT();
		if (opt == "DELETE")
			DELETE();
		if (opt == "REVERSE")
			REVERSE();
		if (opt == "MAKE-SAME")
			MAKE_SAME();
		if (opt == "GET-SUM")
			GET_SUM();
		if (opt == "GET")
			GET();
		if (opt == "MAX-SUM"){
			Gets();
			MAX_SUM();
			
		}
			
//		Gets();
	}
}

回复

5 条回复,欢迎继续交流。

正在加载回复...