本人调线段树调的快疯了,30分求助,样例都是错的。
#include<bits/stdc++.h>
#define MAXN 500001
#define int long long
using namespace std;
const int inf=0x7fffffff;
int n,m,a[MAXN],opt,l,r,k,v;
struct Potential_SegmentTree {
int l,r,cnt,sum,add1,add2,add3,add4,fm1,fm2,sm;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define cnt(x) tree[x].cnt
#define sum(x) tree[x].sum
#define add1(x) tree[x].add1
#define add2(x) tree[x].add2
#define add3(x) tree[x].add3
#define add4(x) tree[x].add4
#define fm1(x) tree[x].fm1
#define fm2(x) tree[x].fm2
#define sm(x) tree[x].sm
#define ls(x) x<<1
#define rs(x) x<<1|1
}tree[MAXN<<2];
void merge(int p) {
sum(p)=sum(ls(p))+sum(rs(p));
fm1(p)=max(fm1(ls(p)),fm1(rs(p)));
fm2(p)=max(fm2(ls(p)),fm2(rs(p)));
if(fm1(ls(p))<fm1(rs(p))) {
sm(p)=max(fm1(ls(p)),sm(rs(p)));
cnt(p)=cnt(rs(p));
}
if(fm1(ls(p))==fm1(rs(p))) {
sm(p)=max(sm(ls(p)),sm(rs(p)));
cnt(p)=cnt(ls(p))+cnt(rs(p));
}
if(fm1(ls(p))>fm1(rs(p))) {
sm(p)=max(sm(ls(p)),fm1(rs(p)));
cnt(p)=cnt(ls(p));
}
}
void spread_(int p,int num1,int num2,int num3,int num4) {
sum(p)+=num1*cnt(p)+num3*(r(p)-l(p)+1-cnt(p));
fm1(p)+=num1;
fm2(p)=max(fm2(p),fm1(p)+num2);
add1(p)+=num1;
add2(p)+=num3;
add3(p)=max(add3(p),add1(p)+num2);
add4(p)=max(add4(p),add2(p)+num4);
if(sm(p)!=-inf) sm(p)+=num3;
}
void spread(int p) {
int maxn=max(fm1(ls(p)),fm1(rs(p)));
if(fm1(ls(p))==maxn) spread_(ls(p),add1(p),add3(p),add2(p),add4(p));
else spread_(ls(p),add2(p),add4(p),add2(p),add4(p));
if(fm1(rs(p))==maxn) spread_(rs(p),add1(p),add3(p),add2(p),add4(p));
else spread_(rs(p),add2(p),add4(p),add2(p),add4(p));
add1(p)=0;
add2(p)=0;
add3(p)=0;
add4(p)=0;
}
void build(int p,int l,int r) {
l(p)=l,r(p)=r;
if(l==r) {
sum(p)=a[l];
fm1(p)=a[l];
fm2(p)=a[l];
sm(p)=-inf;
cnt(p)=1;
return;
}
int mid=l+r>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
merge(p);
}
void change1(int p,int l,int r,int d) {
if(l(p)>r||r(p)<l) return;
if(l<=l(p)&&r(p)<=r) {
spread_(p,d,d,d,d);
return;
}
spread(p);
change1(ls(p),l,r,d);
change1(rs(p),l,r,d);
merge(p);
}
void change2(int p,int l,int r,int v) {
if(l(p)>r||r(p)<l||v>=fm1(p)) return;
if(l<=l(p)&&r(p)<=r&&v>sm(p)) {
spread_(p,v-fm1(p),v-fm1(p),0,0);
return;
}
spread(p);
change2(ls(p),l,r,v);
change2(rs(p),l,r,v);
merge(p);
}
int ask1(int p,int l,int r) {
if(l(p)>r||r(p)<l) return 0;
if(l<=l(p)&&r(p)<=r) return sum(p);
spread(p);
return ask1(ls(p),l,r)+ask1(rs(p),l,r);
}
int ask2(int p,int l,int r) {
if(l(p)>r||r(p)<l) return -inf;
if(l<=l(p)&&r(p)<=r) return fm1(p);
spread(p);
return max(ask2(ls(p),l,r),ask2(rs(p),l,r));
}
int ask3(int p,int l,int r) {
if(l(p)>r||r(p)<l) return -inf;
if(l<=l(p)&&r(p)<=r) return fm2(p);
spread(p);
return max(ask3(ls(p),l,r),ask3(rs(p),l,r));
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++) {
cin>>opt>>l>>r;
if(opt==1) {
cin>>k;
change1(1,l,r,k);
}
if(opt==2) {
cin>>v;
change2(1,l,r,v);
}
if(opt==3) cout<<ask1(1,l,r)<<endl;
if(opt==4) cout<<ask2(1,l,r)<<endl;
if(opt==5) cout<<ask3(1,l,r)<<endl;
}
return 0;
}
求助QAQ