描述
给定 n 个数,第 i(1<=i<=n)个位置上的值为xi,有 m 个操作分为两种操作:
将 x 数组位置 pos 上的数字改为 v
如果选择 x 数组[L,R]中的某连续三个数加 u,新得到的数组称为 y,求所有 可能形成的 y 数组的各元素绝对值之和的最大值(操作 2 不会改变 x 数组)。
输入
第一行输入 n 和 m,接下来一行,有 n 个数表示 x 数组;接下来 m 行,每行先 有一个数 op 表示操作为哪种操作,如果是 1,接下来两个数表示 pos, v;
如果是 2,接下来三个数表示 L, R, u。
输出
对于每个操作 2 输出答案。
样例输入
5 3
-2 -1 0 1 2
2 1 5 1
1 3 1
2 2 5 -1
样例输出
9
6
提示
对于 30%的数据有 3<=n,m<=1000。
对于 60%的数据有 3<=n,m<=30000。
对于 100%的数据有 3<=n,m<=100000, 1<=pos<=n, 1<=L<R<=n,R-L>=2,
1<=op<=2,其他未说明变量保证在整型范围内
【样例解释】
第一次操作可以得到的数组 y 有 3 种:
[-1, 0, 1, 1, 2], [-2, 0, 1, 2, 2], [-2, -1, 1, 2, 3] 其中绝对值的和最大的是[-2, -1, 1, 2, 3]为 9;
第二次操作将数组 x 改为[-2, -1, 1, 1, 2];
第三次操作可以得到的数组 y 有 2 种: [-2, -2, 0, 0, 2], [-2, -1, 0, 0, 1] 其中绝对值的和最大的是[-2, -2, 0, 0,2]
解析:
我们发现三元组分别取正负一共只有8种情况。
(
a
,
b
,
c
)
→
a
b
s
(
a
+
v
)
+
a
b
s
(
b
+
v
)
+
a
b
s
(
c
+
v
)
(a,b,c)\rightarrow abs(a+v)+abs(b+v)+abs(c+v)
(a,b,c)→abs(a+v)+abs(b+v)+abs(c+v)
+
a
+
v
+
b
+
v
+
c
+
v
=
a
+
b
+
c
+
3
v
−
a
−
v
+
b
+
v
+
c
+
v
=
−
a
+
b
+
c
+
v
+
a
+
v
−
b
−
v
+
c
+
v
=
a
−
b
+
c
+
v
−
a
−
v
−
b
−
v
+
c
+
v
=
−
a
−
b
+
c
−
v
+
a
+
v
+
b
+
v
−
c
−
v
=
a
+
b
−
c
+
v
−
a
−
v
+
b
+
v
−
c
−
v
=
−
a
+
b
−
c
−
v
+
a
+
v
−
b
−
v
−
c
−
v
=
a
−
b
−
c
−
v
−
a
−
v
−
b
−
v
−
c
−
v
=
−
a
−
b
−
c
−
3
v
\begin{aligned} +a+v+b+v+c+v&=&a+b+c+3v\\-a-v+b+v+c+v&=&-a+b+c+v\\+a+v-b-v+c+v&=&a-b+c+v\\-a-v-b-v+c+v&=&-a-b+c-v\\+a+v+b+v-c-v&=&a+b-c+v\\-a-v+b+v-c-v&=&-a+b-c-v\\+a+v-b-v-c-v&=&a-b-c-v\\-a-v-b-v-c-v&=&-a-b-c-3v \end{aligned}
+a+v+b+v+c+v−a−v+b+v+c+v+a+v−b−v+c+v−a−v−b−v+c+v+a+v+b+v−c−v−a−v+b+v−c−v+a+v−b−v−c−v−a−v−b−v−c−v========a+b+c+3v−a+b+c+va−b+c+v−a−b+c−va+b−c+v−a+b−c−va−b−c−v−a−b−c−3v
我们发现其实取abs之和的结果就是这8个式子的最大值。
所以我们分别维护这8个变量就行了。
其实这道题的数据怎么出都卡不了常数,但是我闲得无聊写了一发循环展开。。。
然后就校内OJrk1了。
原来的rk1还是在数据加强之前上去的。。。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline ll getint(){
re char c;
re bool f=0;
while(!isdigit(c=gc()))if(c=='-')f=1;re ll num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return f?-num:num;
}
}
using namespace IO;
cs int N=1e5+5;
cs ll INF=0x3f3f3f3f3f3f;
int n,m;
ll a[N];
ll mx[N<<2][8];
ll add[N<<2],ans[8];
ll sum;
int coef[8]={3,1,1,-1,1,-1,-1,-3};//0 + 1 -
inline void init(int k,int pos){
ll *A=a+pos,*B=mx[k];
ll tmp=sum-abs(A[0])-abs(A[1])-abs(A[2]);
B[0]=tmp+A[0]+A[1]+A[2];
B[1]=tmp-A[0]+A[1]+A[2];
B[2]=tmp+A[0]-A[1]+A[2];
B[3]=tmp-A[0]-A[1]+A[2];
B[4]=tmp+A[0]+A[1]-A[2];
B[5]=tmp-A[0]+A[1]-A[2];
B[6]=tmp+A[0]-A[1]-A[2];
B[7]=tmp-A[0]-A[1]-A[2];
}
inline void pushup(int k){
ll *K=mx[k],*lc=mx[k<<1],*rc=mx[k<<1|1];
K[0]=max(lc[0],rc[0]);
K[1]=max(lc[1],rc[1]);
K[2]=max(lc[2],rc[2]);
K[3]=max(lc[3],rc[3]);
K[4]=max(lc[4],rc[4]);
K[5]=max(lc[5],rc[5]);
K[6]=max(lc[6],rc[6]);
K[7]=max(lc[7],rc[7]);
}
inline void pushnow(int k,ll val){
add[k]+=val;
ll *K=mx[k];
K[0]+=val;K[1]+=val;
K[2]+=val;K[3]+=val;
K[4]+=val;K[5]+=val;
K[6]+=val;K[7]+=val;
}
inline void pushdown(int k){
if(add[k]){
pushnow(k<<1,add[k]);
pushnow(k<<1|1,add[k]);
add[k]=0;
}
}
inline void build(int k,cs int &l,cs int &r){
if(l==r)return init(k,l);
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
inline void update(int k,cs int &l,cs int &r,cs int &ql,cs int &qr){
if(l==r)return init(k,l);
pushdown(k);
int mid=(l+r)>>1;
if(ql<=mid)update(k<<1,l,mid,ql,qr);
if(mid<qr)update(k<<1|1,mid+1,r,ql,qr);
pushup(k);
}
inline void modify(int k,cs int &l,cs int &r,cs int &ql,cs int &qr,cs ll &val){
if(ql<=l&&r<=qr)return pushnow(k,val);
pushdown(k);
int mid=(l+r)>>1;
if(ql<=mid)modify(k<<1,l,mid,ql,qr,val);
if(mid<qr)modify(k<<1|1,mid+1,r,ql,qr,val);
pushup(k);
}
inline void get_ans(int k){
ll *K=mx[k];
ans[0]=max(ans[0],K[0]);
ans[1]=max(ans[1],K[1]);
ans[2]=max(ans[2],K[2]);
ans[3]=max(ans[3],K[3]);
ans[4]=max(ans[4],K[4]);
ans[5]=max(ans[5],K[5]);
ans[6]=max(ans[6],K[6]);
ans[7]=max(ans[7],K[7]);
}
inline void query(int k,cs int &l,cs int &r,cs int &ql,cs int &qr){
if(ql<=l&&r<=qr)return get_ans(k);
pushdown(k);
int mid=(l+r)>>1;
if(ql<=mid)query(k<<1,l,mid,ql,qr);
if(mid<qr)query(k<<1|1,mid+1,r,ql,qr);
}
inline ll getans(ll v){
ll res=-INF;
res=max(res,ans[0]+(ll)v*coef[0]);
res=max(res,ans[1]+(ll)v*coef[1]);
res=max(res,ans[2]+(ll)v*coef[2]);
res=max(res,ans[3]+(ll)v*coef[3]);
res=max(res,ans[4]+(ll)v*coef[4]);
res=max(res,ans[5]+(ll)v*coef[5]);
res=max(res,ans[6]+(ll)v*coef[6]);
res=max(res,ans[7]+(ll)v*coef[7]);
return res;
}
signed main(){
n=getint();m=getint();
for(int re i=1;i<=n;++i)sum+=abs(a[i]=getint());
build(1,1,n-2);
while(m--){
switch(getint()){
case 1:{
int pos=getint();
ll v=getint();
ll delta=abs(v)-abs(a[pos]);
sum+=delta;
a[pos]=v;
update(1,1,n-2,pos-2,pos);
if(pos>3)modify(1,1,n-2,1,pos-3,delta);
if(pos<n-2)modify(1,1,n-2,pos+1,n-2,delta);
break;
}
case 2:{
int l=getint(),r=getint();
ll v=getint();
memset(ans,-INF,sizeof ans);
query(1,1,n-2,l,r-2);
cout<<getans(v)<<"\n";
break;
}
}
}
return 0;
}