题目:

样例输入:
9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
输出:
-1
10
1
10
我用的是非旋平衡树(FHQ),
然而我这里在修改过数列之后,
维护的 sum 值和 maxx 值都出问题了(即 区间和 和 最大子区间和 的值)。
有没有大佬帮帮忙。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+5;
int n,m,idx=0,root,dl,dr;
struct FHQ {
int key,val,ls,rs,siz,flag;
int sum,lsum,rsum,maxx;
bool tag;
}tr[maxn];
int add(int key) {
tr[++idx].key=key;
tr[idx].val=rand();
tr[idx].siz=1;
tr[idx].sum=key;
tr[idx].flag=-1000;
if(key>=0) {
tr[idx].lsum=key;
tr[idx].rsum=key;
tr[idx].maxx=key;
}
return idx;
}
inline void pushup(int spot) {
tr[spot].siz=tr[tr[spot].ls].siz+tr[tr[spot].rs].siz+1;
tr[spot].sum=tr[tr[spot].ls].sum+tr[tr[spot].rs].sum+tr[spot].key;
tr[spot].lsum=max(tr[tr[spot].ls].lsum,tr[tr[spot].ls].sum+tr[tr[spot].rs].lsum+tr[spot].key);
tr[spot].rsum=max(tr[tr[spot].rs].rsum,tr[tr[spot].rs].sum+tr[tr[spot].ls].rsum+tr[spot].key);
tr[spot].maxx=max(tr[tr[spot].ls].maxx,tr[tr[spot].rs].maxx);
tr[spot].maxx=max(tr[tr[spot].ls].rsum+tr[tr[spot].rs].lsum+tr[spot].key,tr[spot].maxx);
}
inline void pushdown(int spot) {
if(tr[spot].flag!=-1000) {
tr[tr[spot].ls].key=tr[spot].flag;
tr[tr[spot].rs].key=tr[spot].flag;
tr[tr[spot].ls].flag=tr[spot].flag;
tr[tr[spot].rs].flag=tr[spot].flag;
tr[spot].flag=-1000;
}
if(!tr[spot].tag) return ;
tr[tr[spot].ls].tag^=1;
tr[tr[spot].rs].tag^=1;
swap(tr[spot].ls,tr[spot].rs);
tr[spot].tag=0;
}
void split(int spot,int k,int& l,int& r) {
if(!spot) {
l=r=0;
return ;
}
pushdown(spot);
int cnt=tr[tr[spot].ls].siz+1;
if(cnt<=k) {
l=spot;
split(tr[spot].rs,k-cnt,tr[l].rs,r);
}
else {
r=spot;
split(tr[spot].ls,k,l,tr[r].ls);
}
pushup(spot);
}
int merge(int l,int r) {
if(!l||!r) return l|r;
pushdown(l);
pushdown(r);
if(tr[l].val<=tr[r].val) {
tr[l].rs=merge(tr[l].rs,r);
pushup(l);
return l;
}
else {
tr[r].ls=merge(l,tr[r].ls);
pushup(r);
return r;
}
}
void rever(int L,int len) {
int t1,t2,t3,t4;
split(root,L-1,t1,t2);
split(t2,len,t3,t4);
tr[t3].tag^=1;
t2=merge(t3,t4);
root=merge(t1,t2);
}
void update(int pos,int len,int k) {
split(root,pos-1,dl,dr);
int t1,t2;
split(dr,len,t1,t2);
tr[t1].key=k;
tr[t1].flag=k;
dr=merge(t1,t2);
root=merge(dl,dr);
}
void print(int spot) {
if(!spot) return ;
// pushdown(spot);
// pushup(spot);
print(tr[spot].ls);
printf("%d ",tr[spot].key);
print(tr[spot].rs);
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
int a;
scanf("%d",&a);
root=merge(root,add(a));
}
while(m--) {
string opt;
cin>>opt;
if(opt=="INSERT") {
int pos,tot;
scanf("%d%d",&pos,&tot);
split(root,pos,dl,dr);
while(tot--) {
int a;
scanf("%d",&a);
dl=merge(dl,add(a));
}
root=merge(dl,dr);
}
else if(opt=="DELETE") {
int pos,tot;
scanf("%d%d",&pos,&tot);
split(root,pos-1,dl,dr);
int t1,t2;
split(dr,tot,t1,t2);
root=merge(dl,t2);
}
else if(opt=="MAKE-SAME") {
int pos,tot,c;
scanf("%d%d%d",&pos,&tot,&c);
update(pos,tot,c);
}
else if(opt=="REVERSE") {
int pos,tot;
scanf("%d%d",&pos,&tot);
rever(pos,tot);
}
else if(opt=="GET-SUM") {
int pos,tot;
scanf("%d%d",&pos,&tot);
split(root,pos-1,dl,dr);
int t1,t2;
split(dr,tot,t1,t2);
// print(t1);
// cout<<endl;
printf("%d\n",tr[t1].sum);
dr=merge(t1,t2);
root=merge(dl,dr);
}
else if(opt=="MAX-SUM") {
// print(root);
// cout<<endl;
printf("%d\n",tr[root].maxx);
}
}
return 0;
}
//2 -6 6 -3 -5 2 2 2 -5 7 2