D. Three Sequences
D. Three Sequences
题意:给定一个长度为
n
n
n的序列
a
[
]
a[]
a[],要求把他分成两个序列
b
[
]
,
c
[
]
b[],c[]
b[],c[]
- a [ i ] = b [ i ] + c [ i ] a[i]=b[i]+c[i] a[i]=b[i]+c[i]
- b [ ] b[] b[]是一个非递减序列
- c [ ] c[] c[]是一个非递增序列
- m a x ( b i , c i ) max(b_i,c_i) max(bi,ci)尽可能小
之后有
q
(
1
e
5
)
q(1e5)
q(1e5)次对于
a
[
]
a[]
a[]的修改,给定
l
,
r
,
x
l,r,x
l,r,x:对
[
l
,
r
]
[l,r]
[l,r]范围内的
a
i
a_i
ai都增加
x
x
x
要求给出整个序列中的
m
a
x
(
m
a
x
(
b
i
,
c
i
)
)
max(max(b_i,c_i))
max(max(bi,ci))
思路:看见 q q q次修改,想到差分序列,但是这题在想到用差分时候还是差了一点,手推一下感觉好像还要处理每次之前的最大值,用线段树或者树状数组记录修改。其实不仅仅对于数列 a [ ] a[] a[]需要进行差分,还要对于 b [ ] 、 c [ ] b[]、c[] b[]、c[]进行差分分析
- 由于 b [ ] b[] b[]是一个非递减序列。 c [ ] c[] c[]是一个非递增序列,那么对于 b [ ] b[] b[]的差分数列而言,每个都大于0;对于 c [ ] c[] c[]的每个差分数列而言,每个都小于0。
- 由递增以及递减关系,可以把题目所求答案的 m a x ( m a x ( b i , c i ) ) max(max(b_i,c_i)) max(max(bi,ci))变成 m a x ( b n , c 1 ) max(b_n,c_1) max(bn,c1)
- 问题就转换成了把 a [ ] 的 差 分 数 列 d a [ ] a[]的差分数列da[] a[]的差分数列da[]拆分成一个正数(或0)和一个负数(或0),下面就是需要拆分的策略了。
- 对于题里面给定的样例推理一下就可以发现:
- 如果目前的 d a i da_i dai为正数,就直接全给 b i b_i bi,而 c i c_i ci则加上 0 0 0。 因为如果变成一个正数 K K K和负数 k k k,那么 K > d a i K>da_i K>dai一定成立,这就会造成 b n b_n bn的增大。
- 同理,如果目前的 d a i da_i dai为负数,就直接全给 c i c_i ci,而 b i b_i bi则加上 0 0 0。 因为如果变成一个正数 K K K和负数 k k k,那么 k < d a i k<da_i k<dai一定成立,这就会造成 c 1 c_1 c1的增大。
- 经过上述的两个操作我已经能够保证 b [ ] , c [ ] b[],c[] b[],c[]的增减性了。现在就相当于已经知道了初值分别是 b 1 , c 1 ( 在 这 里 我 设 b i 为 x ) b_1,c_1(在这里我设b_i为x) b1,c1(在这里我设bi为x)的函数(雾?)。那么现在我只要合理分配初始值,就能使得 m a x ( b n , c 1 ) max(b_n,c_1) max(bn,c1)最小化。因为这里的 c 1 = a 1 − x c_1=a_1-x c1=a1−x是一个已知值。我要求的就是 b n = x + ∑ i = 2 n m a x ( 0 , d a i ) b_n=x+\sum_{i=2}^n max(0,da_i) bn=x+∑i=2nmax(0,dai)
- 这里把他们均分当然就是最小的时候,即 x + ∑ i = 2 n m a x ( 0 , d a i ) = a 1 − x x+\sum_{i=2}^n max(0,da_i)=a_1-x x+∑i=2nmax(0,dai)=a1−x,在下面的代码中我把 ∑ i = 2 n m a x ( 0 , d a i ) \sum_{i=2}^n max(0,da_i) ∑i=2nmax(0,dai)用 m a x x maxx maxx表示
接下来留给我的就是对于差分序列的维护,因为其实每次只修改了
a
l
,
a
r
+
1
a_l,a_{r+1}
al,ar+1两个值,所以只要修改前判断是否大于0,减去大于0的,修改后判断是否大于零再加上就好了。
尤其注意1和n的位置!!!这里的差分序列不作数^^(wa4)
LL a[maxn], da[maxn];//差分序列,L-R +1 a[l]+1,a[r+1]-1
LL n, q, xx, ans;
int main()
{
cin >> n;
LL maxx = 0;
da[1] = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (i != 1)da[i] = a[i] - a[i - 1];
if (da[i] > 0) {
maxx += da[i];
}
}
xx = (a[1] - maxx) / 2;
ans = max(a[1] - xx, xx + maxx);
cout << ans << endl;
cin >> q;
LL l, r, x;
for (int i = 1; i <= q; i++) {
cin >> l >> r >> x;
if (l != 1 && da[l] > 0)maxx -= da[l];
if (r != n && da[r + 1] > 0)maxx -= da[r + 1];
if (l != 1)da[l] += x;
if (l == 1)a[1] += x;
if (r != n)da[r + 1] -= x;
if (l != 1 && da[l] > 0)maxx += da[l];
if (r != n && da[r + 1] > 0)maxx += da[r + 1];
xx = (a[1] - maxx) / 2;
ans = max(a[1] - xx, xx + maxx);
cout << ans << endl;
}
return 0;
}