F. Fafa and Array
time limit per test
3 secondsmemory limit per test
256 megabytesinput
standard inputoutput
standard outputFafa has an array A of n positive integers, the function f(A) is defined as . He wants to do q queries of two types:
- 1 l r x — find the maximum possible value of f(A), if x is to be added to one element in the range [l, r]. You can choose to which element to add x.
- 2 l r x — increase all the elements in the range [l, r] by value x.
Note that queries of type 1 don't affect the array elements.
Input
The first line contains one integer n (3 ≤ n ≤ 105) — the length of the array.
The second line contains n positive integers a1, a2, ..., an (0 < ai ≤ 109) — the array elements.
The third line contains an integer q (1 ≤ q ≤ 105) — the number of queries.
Then q lines follow, line i describes the i-th query and contains four integers ti li ri xi .
It is guaranteed that at least one of the queries is of type 1.
Output
For each query of type 1, print the answer to the query.
Examples
input
Copy
5
1 1 1 1 1
5
1 2 4 1
2 2 3 1
2 4 4 2
2 3 4 1
1 3 3 2
output
2
8
input
5
1 2 3 4 5
4
1 2 4 2
2 2 4 1
2 3 4 1
1 2 4 2
output
6
10
(没有qls 灵活的数学分析能力 弱鸡只能用分类来讨论分段函数 不过跑的飞快哦
#include <bits/stdc++.h>
#define ll long long
#define N 100005
using namespace std;
ll readll(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int readint(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
typedef struct node{
int l,r;ll minn;
}node;
node d[N<<2];
int n,q;
ll a[N],ans,b[N];
void up(int x){
d[x].minn=min(d[x<<1].minn,d[x<<1|1].minn);
}
void built(int root,int l,int r){
if(l==r){
d[root].l=d[root].r=l;d[root].minn=b[l];
return ;
}
int mid=(l+r)>>1;
built(root<<1,l,mid);
built(root<<1|1,mid+1,r);
d[root].l=d[root<<1].l;d[root].r=d[root<<1|1].r;
up(root);
}
void update(int root,int t,ll vul){
if(d[root].l==d[root].r){
d[root].minn=vul;
return ;
}
int mid=(d[root].l+d[root].r)>>1;
if(t<=mid) update(root<<1,t,vul);
if(t>mid) update(root<<1|1,t,vul);
up(root);
}
ll ans1;
void querty(int root,int l,int r){
if(l<=d[root].l&&d[root].r<=r){
ans1=min(d[root].minn,ans1);
return ;
}
int mid=(d[root].l+d[root].r)>>1;
if(l<=mid) querty(root<<1,l,r);
if(r>mid) querty(root<<1|1,l,r);
}
ll jue(ll x){
if(x<0) return -1*x;
else return x;
}
ll chulil(ll x){
ll sum1=ans;
ll tt=max(0ll,-1*a[1]);
//sum1+=(x-2*tt);
if(tt==0) sum1+=x;
else{
if(x>=2*tt) sum1+=(x-2*tt);
else if(x>=tt&&x<2*tt) sum1-=(2*tt-x);
else sum1-=x;
}
return sum1;
}
ll chulin(ll x){
ll sum1=ans;
ll tt=max(0ll,a[n-1]);
//sum1+=(x-2*tt);
if(tt==0) sum1+=x;
else{
if(x>=2*tt) sum1+=(x-2*tt);
else if(x>=tt&&x<2*tt) sum1-=(2*tt-x);
else sum1-=x;
}
return sum1;
}
ll chulie(int l,ll x){
ll sum1=ans;
ll tt=max(0ll,a[l-1])+max(0ll,-1*a[l]);
ll ttt=min(max(0ll,a[l-1]),max(0ll,-1*a[l]));
ll tttt=max(max(0ll,a[l-1]),max(0ll,-1*a[l]));
// cout<<tt<<" "<<ttt<<" "<<tttt<<endl;
if(x>=tt) sum1+=(x-tt)*2;
else if(x>=tttt&&x<tt) sum1+=(x-tt)*2;
else if(x>=ttt&&x<tttt) sum1+=(-ttt)*2;
else sum1+=(-x)*2;
return sum1;
}
ll slove(int l,int r,ll x){
ll sum1=ans;
if(l==1&&r!=n){
if(r-l==1){
return max(chulil(x),chulie(r,x));
}
ans1=1e18;querty(1,l+1,r);
ans1=min(ans1,x);sum1+=(x-ans1)*2;
return max(chulil(x),sum1);
}
else if(l!=1&&r==n){
if(r-l==1) return max(chulin(x),chulie(l,x));
ans1=1e18;querty(1,l,r-1);
ans1=min(ans1,x);sum1+=(x-ans1)*2;
return max(sum1,chulin(x));
}
else if(l!=1&&r!=n){
ans1=1e18;querty(1,l,r);
//cout<<ans1<<endl;
ans1=min(ans1,x);sum1+=(x-ans1)*2;
return sum1;
}
else{
if(n==3) return max(max(chulil(x),chulin(x)),chulie(2,x));
ans1=1e18;querty(1,l+1,r-1);
ans1=min(ans1,x);sum1+=(x-ans1)*2;
return max(max(chulil(x),chulin(x)),sum1);
}
}
void work(int l,int r,ll x){
if(l==1&&r!=n){
b[r]-=max(0ll,-1*a[r]);b[r+1]-=max(0ll,a[r]);
ans-=jue(a[r]);a[r]+=x;ans+=jue(a[r]);
b[r]+=max(0ll,-1*a[r]);b[r+1]+=max(0ll,a[r]);
update(1,r,b[r]);
if(r<n+1) update(1,r+1,b[r+1]);
}
else if(l!=1&&r==n){
b[l]-=max(0ll,a[l-1]);ans-=jue(a[l-1]);b[l-1]-=max(0ll,-1*a[l-1]);
a[l-1]-=x;ans+=jue(a[l-1]);b[l]+=max(0ll,a[l-1]);b[l-1]+=max(0ll,-1*a[l-1]);
update(1,l,b[l]);
if(l>2) update(1,l-1,b[l-1]);
}
else if(l!=1&&r!=n){
b[l]-=max(0ll,a[l-1]);ans-=jue(a[l-1]);b[l-1]-=max(0ll,-1*a[l-1]);
a[l-1]-=x;ans+=jue(a[l-1]);b[l]+=max(0ll,a[l-1]);b[l-1]+=max(0ll,-1*a[l-1]);
update(1,l,b[l]);
if(l>2) update(1,l-1,b[l-1]);
b[r]-=max(0ll,-1*a[r]);b[r+1]-=max(0ll,a[r]);
ans-=jue(a[r]);a[r]+=x;ans+=jue(a[r]);
b[r]+=max(0ll,-1*a[r]);b[r+1]+=max(0ll,a[r]);
update(1,r,b[r]);
if(r<n-1) update(1,r+1,b[r+1]);
}
}
void print(){
for(int i=2;i<n;i++) cout<<b[i]<<" ";
cout<<endl;
}
int main(){
ios::sync_with_stdio(false);
n=readint();ans=0;
for(int i=1;i<=n;i++) a[i]=readll();a[n+1]=a[n];
for(int i=1;i<=n;i++) a[i]-=a[i+1],ans+=jue(a[i]);
for(int i=2;i<n;i++) b[i]=max(0ll,a[i-1])+max(0ll,-1*a[i]);
//print();
built(1,1,n);
q=readint();int op,l,r;ll x;
for(int i=1;i<=q;i++){
op=readint();l=readint();r=readint();x=readll();
if(op==1){
//cout<<ans<<endl;
if(l==r){
if(l==1){
printf("%lld\n",chulil(x));
continue;
}
else if(l==n){
printf("%lld\n",chulin(x));
continue;
}
else{
printf("%lld\n",chulie(l,x));
continue;
}
}
printf("%lld\n",slove(l,r,x));
}
else work(l,r,x);
//cout<<ans<<endl;
//print();
}
return 0;
}