题目链接:传送门
题目思路:
ai = bi + ci , 其中b是非降序列,c是非升序列
ci-1 ≥ ci ↔ ai-1 - bi-1 ≥ ai - bi
bi - bi-1 ≥ ai - ai-1 , bi-1 - bi-2 ≥ ai-1 - ai-2 , ... 不等式叠加可得:
bn - b1 >= sum , 定义 sum = ∑ni=2 di , di = ai - ai-1
bn ≥ sum + b1
又 c1 = a1 - b1
现在要使 ans = max(bn , c1) 最小化且bn 和 c1都是以 b1 为自变量的一次函数, 可得 sum + b1 = a1 - b1 -> b1 = (a1 - sum) /2 (b1 取整数)
由于构造了 查分数组d , 区间修改可以转变为单点修改,然后动态修改sum的值即可;
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 typedef pair<int,int> pii; 5 typedef pair<LL,LL> pLL; 6 #define pb push_back 7 #define mk make_pair 8 #define fi first 9 #define se second 10 #define ls (i<<1) 11 #define rs (i<<1|1) 12 #define mem(a,b) memset(a,b,sizeof(a)) 13 const int N=1e6+5; 14 const int inf=0x3f3f3f3f; 15 LL read() 16 { 17 LL x=0,f=1; 18 char ch=getchar(); 19 while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } 20 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 21 return f*x; 22 } 23 LL a[N],d[N],sum,n; 24 void update(int pos,LL x) 25 { 26 if(pos>1&&pos<=n) sum+=max(0LL,d[pos]+x)-max(0LL,d[pos]); 27 d[pos]+=x; 28 } 29 int main() 30 { 31 n=read(); 32 for(int i=1;i<=n;i++) a[i]=read(); 33 for(int i=1;i<=n;i++) d[i]=a[i]-a[i-1]; 34 for(int i=2;i<=n;i++) sum+=max(d[i],0LL); 35 LL x=(d[1]-sum)/2; 36 printf("%lld ",max(d[1]-x,x+sum)); 37 int m=read(); 38 for(int i=1;i<=m;i++) 39 { 40 LL l=read(),r=read(),y=read(); 41 update(l,y); 42 update(r+1,-y); 43 x=(d[1]-sum)/2; 44 printf("%lld ",max(d[1]-x,x+sum)); 45 } 46 return 0; 47 }