增减序列

戳我进原题
题意: 给定一个长度为 n n n的序列 a a a,每次可以指定一个区间给这个区间的所有数统一加 1 1 1或减 1 1 1,问最少要操作多少次可以使得序列 a a a中的所有数都相同,并且输出最终可能得到的序列个数。
数据范围: 1 ≤ n ≤ 1 0 5 1\leq n\leq 10^5 1n105

题解:
区间的简单操作可以想到差分:
那么定义 a a a的差分序列为 b b b
如果要使得所有数都相同,则使得 b [ 2 ] , b [ 3 ] , . . .   , b [ n ] b[2],b[3],...\ ,b[n] b[2],b[3],... ,b[n]都等于 0 0 0
对于序列 a a a的区间 [ l , r ] [l,r] [l,r]操作即对差分序列 b b b b [ l ] b[l] b[l] b [ r + 1 ] b[r+1] b[r+1]操作
[ l , r ] [l,r] [l,r]区间加 1 1 1时,相当于 b [ l ] = b [ l ] + 1 b[l]=b[l]+1 b[l]=b[l]+1 b [ r + 1 ] = b [ r + 1 ] − 1 b[r+1]=b[r+1]-1 b[r+1]=b[r+1]1
[ l , r ] [l,r] [l,r]区间减 1 1 1时,相当于 b [ l ] = b [ l ] − 1 b[l]=b[l]-1 b[l]=b[l]1 b [ r + 1 ] = b [ r + 1 ] + 1 b[r+1]=b[r+1]+1 b[r+1]=b[r+1]+1
因为我们需要将所有的 b [ 2 , . . .   , n ] b[2,...\ ,n] b[2,... ,n]都操作为 0 0 0,又因为每次需要使得一个 b [ l ] b[l] b[l] 1 1 1或减 1 1 1,另一个 b [ r + 1 ] b[r+1] b[r+1] 1 1 1或加 1 1 1,即 b [ l ] b[l] b[l] b [ r + 1 ] b[r+1] b[r+1]进行相反的操作,所以我们尽可能选择一个需要由负变 0 0 0 b [ i ] b[i] b[i]和一个需要由正变 0 0 0 b [ j ] b[j] b[j],这样一次操作可以操作两个 b b b

当由负变 0 0 0 b [ i ] b[i] b[i]和由正变 0 0 0 b [ j ] b[j] b[j]其中有一个已经没有时,我们之后的操作可以有两个选择,要么选择 b [ 1 ] b[1] b[1],要么选择 b [ n + 1 ] b[n+1] b[n+1],这两者对于最终操作的数量是没有影响的,但是这两者影响的是最少操作数量下会得到不同的序列,即我们可以选择对 b [ 1 ] b[1] b[1]操作 [ 0 , a b s ( p o s , n e g ) ] [0,abs(pos,neg)] [0,abs(pos,neg)]次,故总共是 a b s ( p o s , n e g ) + 1 abs(pos,neg)+1 abs(pos,neg)+1种不同序列。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long ll;
const int N = 1e5 + 10;
ll a[N];
int n;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值