https://codeforces.com/contest/1406/problem/D
菜到爆炸,1个小时20分钟没想出来怎么求这个值
这题就是要求min{max(bn,c1)},然后发现ai和ai-1之间的大小关系可以限制bi,bi-1,ci,ci-1的大小。。。
假设a1=b1+c1, b1=a1-mx,c1=mx
那么由于b1<=b2,c1>=c2
得b2>=a1-mx,b2>=a2-mx ,我们希望b序列递增的尽可能慢来让最后bn尽可能小,所以会取max(a1-mx,a2-mx)
那么a1>=a2时,b1=b2=a1-mx,但是a1<a2时,b2=a2-mx,b1+a2-a1=b2,
设所有相邻差值大于0的差值之和为K,那么bn=a1+K-mx ,而bn本身也就是mx,那么最小值就是2mx=a1+K了
修改操作就只要考虑一下l,l-1和r+1,r的差值即可
用树状数组维护一下每个点的值就行
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,cnt,tot,cas;ll ans;
ll now;
ll a[maxl];
ll b[maxl];
bool vis[maxl];
char s[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
now=0;
for(int i=2;i<=n;i++)
if(a[i-1]<a[i])
now+=a[i]-a[i-1];
}
inline ll sum(int i)
{
ll ret=0;
while(i)
{
ret+=b[i];
i-=i&-i;
}
return ret;
}
inline void add(int i,int x)
{
while(i<=n+1)
{
b[i]+=x;
i+=i&-i;
}
}
inline void mainwork()
{
scanf("%d",&m);
if(a[1]+sum(1)+now>=0)
ans=(a[1]+sum(1)+now+1)/2;
else
ans=(a[1]+sum(1)+now)/2;
printf("%lld\n",ans);
int l,r,x;ll d;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&l,&r,&x);
if(l>1)
{
d=a[l]+sum(l)-a[l-1]-sum(l-1);
if(d>0)
now-=d;
}
if(r<n)
{
d=a[r+1]+sum(r+1)-a[r]-sum(r);
if(d>0)
now-=d;
}
add(l,x);
add(r+1,-x);
if(l>1)
{
d=a[l]+sum(l)-a[l-1]-sum(l-1);
if(d>0)
now+=d;
}
if(r<n)
{
d=a[r+1]+sum(r+1)-a[r]-sum(r);
if(d>0)
now+=d;
}
if(a[1]+sum(1)+now>=0)
ans=(a[1]+sum(1)+now+1)/2;
else
ans=(a[1]+sum(1)+now)/2;
printf("%lld\n",ans);
}
}
int main()
{
int t=1;
//scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
}
return 0;
}