P4552 [Poetize6] 差分

题意

传送门 P4552 [Poetize6] IncDec Sequence

题解

求出 a a a 的差分序列 d d d,其中 d 0 = a 0 , d i = a i − a i − 1 ( 1 ≤ i < n ) d_0=a_0,d_i=a_i-a_{i-1}(1\leq i<n) d0=a0,di=aiai1(1i<n)。令 a n = 0 a_n=0 an=0,那么对区间的操作转化为对序列中两个数的加或减 1 1 1 操作,目标是使 d 1 , d 2 … , d n − 1 d_1,d_2\dots,d_{n-1} d1,d2,dn1 0 0 0,此时序列由 n n n d 0 d_0 d0 组成。对区间 [ i , j ] [i,j] [i,j] 进行操作有 3 3 3 种可能的可以逼近目标的情况:取 b i , b j ( 1 ≤ i , j < n ) b_i,b_j(1\leq i,j <n) bi,bj(1i,j<n),此时单次的操作可以最快地逼近目标,所以应该尽量采取这样的操作;取 b 0 , b j ( 1 ≤ j < n ) b_0,b_j(1\leq j<n) b0,bj(1j<n);取 b i , b n ( 1 ≤ i < n ) b_i,b_n(1\leq i<n) bi,bn(1i<n)

d 1 , d 2 … , d n − 1 d_1,d_2\dots,d_{n-1} d1,d2,dn1 中正数的和为 x x x,负数的和为 y y y。第一种情况最多可执行 m i n ( x , y ) min(x,y) min(x,y) 次操作,第二、三种情况可执行 ∣ x − y ∣ |x-y| xy 次操作;总共 m a x ( x , y ) max(x,y) max(x,y) 次,即最小操作次数。

对差分序列 d d d 求前缀和,可得到最终序列,即由 n n n d 0 d_0 d0 组成的序列。那么不同的序列数等于 d 0 d_0 d0 可能的取值数量,根据上述分析,有 d 0 ∈ [ 0 , ∣ x − y ∣ ] d_0\in [0,|x-y|] d0[0,xy],故不同序列数为 ∣ x − y ∣ + 1 |x-y|+1 xy+1

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 100005
int N;
ll A[maxn], D[maxn];

int main()
{
    scanf("%d", &N);
    for (int i = 0; i < N; ++i)
        scanf("%lld", A + i);
    D[0] = A[0];
    ll x = 0, y = 0;
    for (int i = 1; i < N; ++i)
    {
        D[i] = A[i] - A[i - 1];
        if (D[i] < 0)
            y -= D[i];
        else
            x += D[i];
    }
    ll res = max(x, y), num = abs(x - y) + 1;
    printf("%lld\n%lld\n", res, num);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值