Codeforces Round #465 (Div. 2) F. Fafa and Array
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; }