又是拆绝对值的套路。
绝对值拆掉后有八种情况,绝对值之和一定是这几个里面最大的。
因为
∣
a
+
b
∣
⩾
a
+
b
|a+b| \geqslant a+b
∣a+b∣⩾a+b,
∣
a
+
b
∣
⩾
−
a
−
b
|a+b| \geqslant -a-b
∣a+b∣⩾−a−b。
于是维护一个全局和,维护每个位置连续三位的八种和就完了。
p
u
s
h
u
p
pushup
pushup写错调了
1
h
1h
1h。0皿0
#include<bits/stdc++.h>
#define mid (T[root].l+T[root].r>>1)
#define rc (root<<1|1)
#define lc (root<<1)
#define ll long long
#define re register
#define cs const
using std::max;
cs int N=1e5+10,M=8;
cs ll oo=1e18;
int n,m,op,pos,l,r;
ll a[N],b[N],val,ans,SUM;
ll k[M][4]={
1, 1, 1, 3,
1, 1,-1, 1,
1,-1, 1, 1,
-1, 1, 1, 1,
1,-1,-1,-1,
-1, 1,-1,-1,
-1,-1, 1,-1,
-1,-1,-1,-3
};
inline void Max(ll &x,ll y){if(x<y)x=y;}
namespace IO{
cs int Rlen=1<<22|1;
char buf[Rlen],*p1,*p2;
inline char gc(){return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;}
template<typename T>
inline T get(){
char ch=gc();T x=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=gc();}
while(isdigit(ch)) x=((x+(x<<2))<<1)+(ch^48),ch=gc();
return x*f;
}
inline int gi(){return get<int>();}
inline int gl(){return get<ll>();}
}
using IO::gi;
using IO::gl;
namespace SGT{
struct node{int l,r;ll mx[M];}T[::N<<2];
inline void pushup(int root){
for(int re i=0;i<M;++i)
T[root].mx[i]=max(T[lc].mx[i],T[rc].mx[i]);
}
inline void build(int root,int l,int r){
T[root].l=l,T[root].r=r;
if(l==r){
for(int re i=0;i<M;++i)
T[root].mx[i]=k[i][0]*a[l]+k[i][1]*a[l+1]+k[i][2]*a[l+2]-b[l]-b[l+1]-b[l+2];
return;
}build(lc,l,mid),build(rc,mid+1,r),pushup(root);
}
inline ll query(int root,int l,int r,int id){
if(l<=T[root].l&&T[root].r<=r) return T[root].mx[id];
if(l> mid) return query(rc,l,r,id);
if(r<=mid) return query(lc,l,r,id);
return max(query(lc,l,mid,id),query(rc,mid+1,r,id));
}
inline void update(int root,int pos){
if(T[root].l==T[root].r){
for(int re i=0;i<M;++i)
T[root].mx[i]=k[i][0]*a[pos]+k[i][1]*a[pos+1]+k[i][2]*a[pos+2]-b[pos]-b[pos+1]-b[pos+2];
return;
}(pos<=mid)?update(lc,pos):update(rc,pos);
pushup(root);
}
inline void change(int pos){
if(1<=pos&&pos<=n-2) update(1,pos);
if(2<=pos&&pos<=n-1) update(1,pos-1);
if(3<=pos&&pos<=n ) update(1,pos-2);
}
}
int main(){
// freopen("3374.in","r",stdin);
n=gi(),m=gi();
for(int re i=1;i<=n;++i)
a[i]=gi(),b[i]=(a[i]<0)?-a[i]:a[i],SUM+=b[i];
SGT::build(1,1,n-2);
while(m--){
op=gi();
if(op==1){
pos=gi(),val=gl(),a[pos]=val,SUM-=b[pos];
b[pos]=val<0?-val:val,SUM+=b[pos],SGT::change(pos);
}
if(op==2){
l=gi(),r=gi(),val=gl(),ans=-oo;
for(int re i=0;i<M;++i)
Max(ans,SGT::query(1,l,r-2,i)+k[i][3]*val);
printf("%lld\n",SUM+ans);
}
}
}