Codeforces Round #465 (Div. 2) F. Fafa and Array

F. Fafa and Array
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Fafa 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 lrx — 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 lrx — 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 tilirixi .

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;
}

  

 

posted @ 2018-02-22 02:43  wang9897  阅读(254)  评论(0编辑  收藏  举报