社区讨论
关于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 条回复,欢迎继续交流。
正在加载回复...