C F 1406 D \mathrm{CF1406D} CF1406D
题目意思
给你一个长度为 n n n 的序列 a i a_i ai,让你构造 b i , c i b_i,c_i bi,ci 使得 b i + c i = a i b_i+c_i=a_i bi+ci=ai 并且 b i b_i bi 不降, c i c_i ci 不升,使得 min ( max i = 1 n ( a i , b i ) ) \min(\max\limits_{i=1}^{n}(a_i,b_i)) min(i=1maxn(ai,bi)),并且有 q q q 次修改。 n , q ≤ 1 0 5 n,q\leq 10^5 n,q≤105
S o l \mathrm{Sol} Sol
一道不错的思维题
我们考虑若 a i − 1 < a i a_{i-1}<a_i ai−1<ai 那么 c i = c i − 1 , b i = b i − 1 + ( a i − a i − 1 ) c_i=c_{i-1},b_i=b_{i-1}+(a_i-a_{i-1}) ci=ci−1,bi=bi−1+(ai−ai−1)
若 a i < a i − 1 a_i<a_{i-1} ai<ai−1 那么 b i = b i − 1 , c i = c i − 1 + ( a i − a i − 1 ) b_i=b_{i-1},c_i=c_{i-1}+(a_i-a_{i-1}) bi=bi−1,ci=ci−1+(ai−ai−1)
这个还是比较显然的(利用 b i , c i b_i,c_i bi,ci 不升不降的特殊性质)。
我们设 m x = c 1 mx=c_1 mx=c1,那么 b 1 = a 1 − m x b_1=a_1-mx b1=a1−mx, b n = b 1 + ( S = ∑ i = 2 n max ( 0 , a i − a i − 1 ) ) b_n=b_1+(S=\sum\limits_{i=2}^{n}\max(0,a_i-a_{i-1})) bn=b1+(S=i=2∑nmax(0,ai−ai−1))
那么 m x = a 1 − m x + S mx=a_1-mx+S mx=a1−mx+S 所以 m x = a 1 + S 2 mx=\frac{a1+S}{2} mx=2a1+S。
对于对于带修改我们考虑差分即可,具体地对于一次修改 ( l , r , s ) (l,r,s) (l,r,s)
若 a l > a l − 1 a_l>a_{l-1} al>al−1 那么我们先减去原先的贡献再加上修改后的即 ( a l + s ) (a_l+s) (al+s) 若大于 a l − 1 a_{l-1} al−1 那么加上 a l + s − a l − 1 a_l+s-a_{l-1} al+s−al−1 否则只减不加。
时间复杂度 O ( n + q ) O(n+q) O(n+q)
C o d e \mathrm{Code} Code
const int mod=1e9+7;
const int mo=998244353;
const int N=2e5+5;
int n,m,a[N],cf[N],Q;
signed main()
{
io.read(n);
int mx=0;
For(i,1,n) io.read(a[i]),mx+=(i>1)?max(a[i]-a[i-1],0ll):0;
io.write((a[1]+mx+1)>>1ll),puts("");
Dow(i,n,1) a[i]=a[i]-a[i-1];
io.read(m);
for (;m--;)
{
int l,r,s;
io.read(l),io.read(r),io.read(s);
if(l==1) a[1]+=s;
else
{
if(a[l]>0) mx-=a[l];
a[l]+=s;
if(a[l]>0) mx+=a[l];
}
if(r<n)
{
r++;
if(a[r]>0) mx-=a[r];
a[r]-=s;
if(a[r]>0) mx+=a[r];
}
io.write((a[1]+mx+1)>>1ll),puts("");
}
return 0;
}