CodeForces - 935F Fafa and Array —— 線段樹
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 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
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
題意:
給你n個數,對於f(a)的定義見題目,給你兩個操作,1 l r x 代表你可以在l到r之間選一個數加上x,讓f(a)最大,或者可以不加,2 l r x 代表在l到r之間的所有數都加上x。
題解:
對於第一個操作,我們可以知道,如果 >0的時候,增加ai會減小f(a),在 <0的時候,增加ai會減小f(a),那麼我們只要維護當 >0, <0的時候的和,之後若是小於x,那麼就是ans+2*(x-sum).第二個操作,改變的只是l,l-1,r,r+1範圍的值,稍微修改一下即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
ll a[N],de[N],sum[N<<2];
void update(int l,int r,int root,int pos)
{
if(l==r)
{
ll ans=0;
if(de[pos-1]>0)ans+=de[pos-1];
if(de[pos]<0)ans-=de[pos];
sum[root]=ans;
return ;
}
int mid=l+r>>1;
if(mid>=pos)
update(l,mid,root<<1,pos);
else
update(mid+1,r,root<<1|1,pos);
sum[root]=min(sum[root<<1],sum[root<<1|1]);
}
ll query(int l,int r,int root,int ql,int qr)
{
if(l>=ql&&r<=qr)
return sum[root];
int mid=l+r>>1;
ll ans=1e17;
if(mid>=ql)
ans=query(l,mid,root<<1,ql,qr);
if(mid<qr)
ans=min(ans,query(mid+1,r,root<<1|1,ql,qr));
return ans;
}
int main()
{
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ll all=0;
for(int i=1;i<n;i++)
{
de[i]=a[i]-a[i+1];
all+=abs(de[i]);
if(i>1)
update(1,n,1,i);
}
int op,l,r;
ll x;
scanf("%d",&m);
while(m--)
{
scanf("%d%d%d%lld",&op,&l,&r,&x);
if(op==1)
{
if(l==r)
printf("%lld\n",all-abs(de[l-1])-abs(de[l])+abs(de[l-1]-x)+abs(de[l]+x));
else
{
ll ans=query(1,n,1,l,r);
if(ans>x)
printf("%lld\n",all);
else
printf("%lld\n",all+2*(x-ans));
}
}
else
{
all-=(abs(de[l-1])+abs(de[r]));
de[l-1]-=x,de[r]+=x;
all+=(abs(de[l-1])+abs(de[r]));
update(1,n,1,l),update(1,n,1,r);
if(l-1>1)
update(1,n,1,l-1);
if(r+1<n)
update(1,n,1,r+1);
}
}
return 0;
}