我想偷懒,直接 每个节点分成俩个部分维护(*(-1)和不乘(-1)) , 但是感觉好像又有问题,当然是萎了。
#include <bits/stdc++.h>
#define ls(p) 2*p
#define rs(p) 2*p+1
using namespace std;
const int N=1e5+5;
struct tree {
int maxn[2];
int lmax[2];
int rmax[2];
int sum[2];
int tag;
int L[2];
int R[2];
int Lst[2];
int Rst[2];
tree() {
tag=0;
maxn[0]=lmax[0]=rmax[0]=-2e9;
maxn[1]=lmax[1]=rmax[1]=-2e9;
sum[0]=sum[1]=0;
Lst[0]=Lst[1]=Rst[0]=Rst[1]=0;
}
};
struct oi {
int l,r;
};
tree T[N*4];
int n,q;
int a[N];
stack<oi> s;
tree merge(tree A,tree B) {
tree C;
int id1=A.tag,id2=B.tag;
for(int i=0; i<=1; i++) {
C.sum[i]=A.sum[id1]+B.sum[id2];
C.lmax[i]=A.lmax[id1],C.Lst[i]=A.Lst[id1];
if(A.sum[id1]+B.lmax[id2]>C.lmax[i]) C.lmax[i]=A.sum[id1]+B.lmax[id2],C.Lst[i]=B.Lst[id2];
C.rmax[i]=B.rmax[id2],C.Rst[i]=B.Rst[id2];
if(B.sum[id2]+A.rmax[id1]>C.rmax[i]) C.rmax[i]=B.sum[id2]+A.rmax[id1],C.Rst[i]=A.Rst[id1];
if(A.maxn[id1]>C.maxn[i]) C.maxn[i]=A.maxn[id1],C.L[i]=A.L[id1],C.R[i]=A.R[id1];
if(B.maxn[id2]>C.maxn[i]) C.maxn[i]=B.maxn[id2],C.L[i]=B.L[id2],C.R[i]=B.R[id2];
if(A.rmax[id1]+B.lmax[id2]>C.maxn[i]) C.maxn[i]=A.rmax[id1]+B.lmax[id2],C.L[i]=A.Rst[id1],C.R[i]=B.Lst[id2];
id1^=1,id2^=1;
}
return C;
}
void change(int p,int l,int x) {
int id=T[p].tag;
for(int i=0; i<=1; i++) {
T[p].Lst[id]=T[p].Rst[id]=T[p].L[id]=T[p].R[id]=l;
T[p].sum[id]=T[p].maxn[id]=T[p].lmax[id]=T[p].rmax[id]=x;
id^=1,x=-x;
}
}
void build(int p,int l,int r) {
if(l==r) {
change(p,l,a[l]);
return ;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
T[p]=merge(T[ls(p)],T[rs(p)]);
}
void update(int p,int l,int r,int x,int y) {
if(l==r) {
change(p,l,y);
return ;
}
int mid=(l+r)>>1;
T[ls(p)].tag^=T[p].tag,T[rs(p)].tag^=T[p].tag,T[p].tag=0;
if(x<=mid) update(ls(p),l,mid,x,y);
if(x>mid) update(rs(p),mid+1,r,x,y);
T[p]=merge(T[ls(p)],T[rs(p)]);
}
void update2(int p,int l,int r,int L,int R) {
int mid=(l+r)>>1;
if(L<=l&&r<=R) {
T[p].tag^=1;
return ;
}
T[ls(p)].tag^=T[p].tag,T[rs(p)].tag^=T[p].tag,T[p].tag=0;
if(L<=mid) update2(ls(p),l,mid,L,R);
if(R>mid) update2(rs(p),mid+1,r,L,R);
T[p]=merge(T[ls(p)],T[rs(p)]);
}
tree query(int p,int l,int r,int L,int R) {
if(L<=l&&r<=R) return T[p];
int mid=(l+r)>>1;
T[ls(p)].tag^=T[p].tag,T[rs(p)].tag^=T[p].tag,T[p].tag=0;
if(L>mid) return query(rs(p),mid+1,r,L,R);
if(R<=mid) return query(ls(p),l,mid,L,R);
return merge(query(ls(p),l,mid,L,R),query(rs(p),mid+1,r,L,R));
}
int main() {
cin>>n;
int tot=0;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]),tot+=a[i];
cin>>q;
build(1,1,n);
while(q--) {
int op;
scanf("%d",&op);
if(op==0) {
int x,y;
scanf("%d%d",&x,&y);
update(1,1,n,x,y);
}
if(op==1) {
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
int ans=0;
for(int i=1; i<=k; i++) {
tree tmp=query(1,1,n,l,r);
int p=tmp.tag;
if(tmp.maxn[p]<0) break;
ans+=tmp.maxn[p];
int L_=tmp.L[p];
int R_=tmp.R[p];
update2(1,1,n,L_,R_);
s.push({L_,R_});
}
while(!s.empty()) {
oi tmp=s.top();
update2(1,1,n,tmp.l,tmp.r);
s.pop();
}
printf("%d\n",ans);
}
}
return 0;
}