同一份代码交两次,一次10分一次0分,下载了数据 下来本体跑,但是本地是对的。
感觉是随机数写炸了?求助mt19937有没有错(
#include <bits/stdc++.h>
#define file(x) freopen(x ".in","r",stdin);freopen(x ".out","w",stdout)
#define fp(...) fprintf(stderr,__VA_ARGS__)
#define de(x) cerr << #x << ":" << x << endl;
using namespace std;
inline int read(){
int x = 0,f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
while(ch >= '0'&& ch <= '9'){x = (x << 3) + (x << 1) + ch - 48;ch = getchar();}
return x * f;
}
inline void write(auto x) {
if(x < 0) putchar('-');
static int sta[35];
int tp = 0;
do{sta[tp++] = x % 10, x /= 10;}while(x);
while(tp) putchar(sta[--tp] + '0');
//putchar('\n');
}
bool _mst;
const int N = 6e5 + 100;
int fr[N], tp;
int val[N], dat[N], ls[N], rs[N], siz[N], sum[N], pr[N], sf[N], mx[N];
bool cov[N], rev[N];
int idx, rt;
mt19937 Filberte(random_device{}());
int rnd(){return Filberte();}
// void Debug_Tree(int u){
// if(!u) return ;fp("%d:\nls:%d rs:%d val:%d siz:%d sum:%d pr:%d sf:%d mx:%d\n",u,ls[u],rs[u],val[u],siz[u],sum[u],pr[u],sf[u],mx[u]);
// Debug_Tree(ls[u]);
// Debug_Tree(rs[u]);
// }
void recy(int u){
if(ls[u]) recy(ls[u]);
if(rs[u]) recy(rs[u]);
fr[++tp] = u;
}
int nnod(int x){
int u = tp ? fr[tp--] : ++idx;
val[u] = sum[u] = mx[u] = x;
dat[u] = rnd();
pr[u] = sf[u] = max(0, x);
ls[u] = rs[u] = 0;
cov[u] = rev[u] = 0;
siz[u] = 1;
return u;
}
void push_up(int u){
siz[u] = siz[ls[u]] + siz[rs[u]] + 1;
sum[u] = sum[ls[u]] + sum[rs[u]] + val[u];
pr[u] = max({pr[ls[u]], sum[ls[u]] + val[u] + pr[rs[u]], 0});
sf[u] = max({sf[rs[u]], sum[rs[u]] + val[u] + sf[ls[u]], 0});
mx[u] = sf[ls[u]] + val[u] + pr[rs[u]];
if(ls[u]) mx[u] = max(mx[u], mx[ls[u]]);
if(rs[u]) mx[u] = max(mx[u], mx[rs[u]]);
}
void pcov(int u, int k){
cov[u] = 1;
val[u] = k;
sum[u] = siz[u] * k;
pr[u] = sf[u] = k > 0 ? k * siz[u] : 0;
mx[u] = k > 0 ? k * siz[u] : k;
}
void prev(int u){
rev[u] ^= 1;
swap(ls[u], rs[u]);
swap(pr[u], sf[u]);
}
void push_down(int u){
if((!ls[u] && !rs[u]) || !u) return ;
if(cov[u]){
if(ls[u]) pcov(ls[u], val[u]);
if(rs[u]) pcov(rs[u], val[u]);
cov[u] = 0, rev[u] = 0;
}
else if(rev[u]){
if(ls[u]) prev(ls[u]);
if(rs[u]) prev(rs[u]);
rev[u] = 0;
}
}
pair<int, int> split(int u, int k){ // 1 ~ k || k + 1 ~ siz
if(!u) return make_pair(0, 0);
push_down(u);
if(siz[ls[u]] >= k){
auto [x, y] = split(ls[u], k);
ls[u] = y;
push_up(u);
return make_pair(x, u);
}
else{
auto [x, y] = split(rs[u], k - siz[ls[u]] - 1);
rs[u] = x;
push_up(u);
return make_pair(u, y);
}
}
int merge(int x, int y){
if(!x || !y) return x | y;
push_down(x), push_down(y);
if(dat[x] < dat[y]){
rs[x] = merge(rs[x], y);
push_up(x);
return x;
}
else{
ls[y] = merge(x, ls[y]);
push_up(y);
return y;
}
}
int c[N]; // need to be ins
int ntr(int l, int r){
if(l == r) return nnod(c[l]);
int mid = (l + r) >> 1;
return merge(ntr(l, mid), ntr(mid + 1, r));
}
void ins(int len, int pos){
int now = ntr(1, len);
auto [x, y] = split(rt, pos);
rt = merge(merge(x, now), y);
}
void del(int st, int ed){
auto [t, z] = split(rt, ed);
auto [x, y] = split(t, st - 1);
recy(y);
rt = merge(x, z);
}
void cover(int st, int ed, int k){
auto [t, z] = split(rt, ed);
auto [x, u] = split(t, st - 1);
pcov(u, k);
rt = merge(merge(x, u), z);
}
void reverse(int st, int ed){
auto [t, z] = split(rt, ed);
auto [x, u] = split(t, st - 1);
prev(u);
rt = merge(merge(x, u), z);
}
int get_sum(int st, int ed){
auto [t, z] = split(rt, ed);
auto [x, u] = split(t, st - 1);
int res = sum[u];
rt = merge(merge(x, u), z);
return res;
}
int get_mx(){return mx[rt];}
bool _med;
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n, q;
cin >> n >> q;
for(int i = 1;i <= n;i++) cin >> c[i];
int pos, tot, k;
ins(n, 0);
while(q--){
string op;cin >> op;
if(op[2] == 'S'){ // insert
cin >> pos >> tot;
for(int i = 1;i <= tot;i++) cin >> c[i];
ins(tot, pos);
}
else if(op[2] == 'L'){ // delete
cin >> pos >> tot;
del(pos, pos + tot - 1);
}
else if(op[2] == 'K'){ // make-same
cin >> pos >> tot >> k;
cover(pos, pos + tot - 1, k);
}
else if(op[2] == 'V'){ //reverse
cin >> pos >> tot;
reverse(pos, pos + tot - 1);
}
else if(op[2] == 'T'){ // get-sum
cin >> pos >> tot;
cout << get_sum(pos, pos + tot - 1) << '\n';
}
else{ // max-sum
cout << get_mx() << '\n';
}
}
return 0;
}
/*
10 20
-231 259 -231 -919 -736 609 241 907 -676 -978
INSERT 0 4 987 348 686 -575
MAKE-SAME 7 2 -841
GET-SUM 5 1
MAKE-SAME 8 4 -742
MAX-SUM
MAKE-SAME 7 4 386
GET-SUM 1 5
MAKE-SAME 2 2 -36
MAX-SUM
GET-SUM 5 3
MAKE-SAME 10 2 579
MAX-SUM
INSERT 9 3 -822 -949 -505
GET-SUM 12 5
INSERT 5 4 934 -427 -839 660
DELETE 3 4
DELETE 5 4
REVERSE 2 8
MAKE-SAME 5 3 772
REVERSE 7 6
*/