D. Three Sequences(思维+数学+差分维护)详解

https://codeforces.com/contest/1406/problem/D


题意:给一段序列ai,构造一个bi和ci,使得bi+ci=ai,且bi单调不减,ci单调不增,求最小的max(bi,ci);多次修改[l,r]上的数+=d,再问max(ai,bi)

思路:初看此题,比较明显的是要差分维护,但是这题的关键是数学推导。

比如样例a=2,-1,7,3;

此时ai-ai-1的差分为-3,8,-4;

第一步:

设b1=x,c1=y;可以得到

b1<=b2<=b3<=b4.....<=bn;c1>=c2>=c3>=c4...>=cn;

答案在bn和c1中取一个较大的。

这时候发现,由于b是单调递增的,由差分可得,后面的数比如b2,在b1的基础上给的是正差分。c是单调递减的,后面的数比如c2,在c1的基础上给的是负差分。

比如:x+y=a1;

扫描二维码关注公众号,回复: 11671442 查看本文章

c2=c1+(-3);b2=b1的时候,这时候满足了题目的b2+c2==a2的条件,同时满足b2和c2的单调性条件。

当到了8这个正差分的时候,会发现如果把8拆一下比拆成-4和12,然后分别给b2+12,c2-4,这样只会让后面的bn更大。比直接把这个8给b2,c2给0来得更大。

所以现在推出来正差分给b,负差分给c.

那么有 x<=x<=x+8<=x+8

y>=y-3>=y-3>=y-7;

ans=min(x+8,y);由于x+y==a[1]=2;

所以ans=min(x+8,2-x)当两者相等取最小,x+8=2-x;x=(a1-d)/2;

这个8就是正差分的和,这个2就是a[1]。

那么就是说维护序列的a[1]和正差分之和就可以了。

tot为正差分之和

LL x=(cnt[1]-tot)/2;
cout<<max(x+tot,cnt[1]-x)<<endl;

然后碰到了修改区间时候,区间内部的差分是不变的(同加d)。只有在交界处cnt[l]和cnt[r+1]的时候谈论一下d的正负对tot的影响,然后更新。

参考了博客:https://blog.csdn.net/qq_20252251/article/details/108558104

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL a[maxn],cnt[maxn];
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;cin>>n;
  LL tot=0;//正差分之和 
  for(LL i=1;i<=n;i++) cin>>a[i];
  for(LL i=1;i<=n;i++) cnt[i]=a[i]-a[i-1];//cnt[1]是a[1]
  for(LL i=1;i<=n;i++){
  	if(cnt[i]>0&&i!=1) tot+=cnt[i];
  } 
  LL x=(cnt[1]-tot)/2;
  cout<<max(x+tot,cnt[1]-x)<<endl;
  LL q;cin>>q;
  while(q--)
  {
  	LL l,r,d;cin>>l>>r>>d;
	if(l==1) cnt[1]+=d; 
	else{
		//如果调整的值是负数,考虑调整到的差分有没有正变负 
		if(d<0){
			if(cnt[l]>0) tot-=min(cnt[l],-d);
		} 
		else{
			//正数调整正差分 
			if(cnt[l]+d>=0) tot+=min(cnt[l]+d,d);
		}
		cnt[l]+=d;//更新 
	}	
	if(r+1<=n){
		if(d>0){
			if(cnt[r+1]>0) tot-=min(cnt[r+1],d);
		}
		else{
			if(cnt[r+1]-d>=0) tot+=min(cnt[r+1]-d,-d);
		}
		cnt[r+1]-=d;
	}
	x=(cnt[1]-tot)/2;
	cout<<max(x+tot,cnt[1]-x)<<endl;
  }
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108560630