[Poetize6] IncDec Sequence 差分

题目描述

给定一个长度为n的数列a1,a2,⋯,an a1​,a2​,⋯,an​,每次可以选择一个区间[l,r] ,使这个区间内的数都加1或者都减1。

请问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。

 

题解:

dif 表示 a[i]与a[i-1]的差值,将a[1]定为基,则对这个差值组成的数组只要令2到n项都为0,求出最小操作次数以及最后基值a[1]有多少可能。

  对差值连续的两个数, 正数(X)和负数(Y),要通过N = min(X,abs(Y))让其中一方变为0.

    对一个正数(X)要通过N = abs(X)让其变为0.

    对一个负数(Y)要通过N = abs(Y)让其变为0.

   在这个过程,我们发现正数和负数可以抵消。例如对 2 5 1,dif是 3 -4,需要min(3,abs(-4))=3步让其中一个为0,对原数组操作就是5减三变成2.   这时原数组就是2,2,1,而此时dif 差值数组是 0,-1.  这-4抵消了3次变成-1,还要经过1次才行,我们发现abs(-4)-3 =1,于是多试几次得出结论对一个正数(X)和负数(Y)都变成0 需要经过 min(X,abs(Y))+abs(X-Y)==max(X,abs(Y))次.

这个结论从连续的两个数推广到整个差值数组,定义totz是所有正数的和,totf是所有负数的和比较两者最大值即为最小操作次数

那会有多少种可能呢?

从上面看出所有差值为正的和totz与所有差值为负的绝对值的和totf  两种中小者是抵消的次数,最后还剩下 abs(X-Y)次操作是改变整个数列值的操作。例如 totz = 6,totf = 5,5次是可以看作正负抵消,最后一次是确定整个数列的值。又例如上面例子2,5,1

3次抵消变成2,2,1最后一次操作让最后一个数加一是确定整个数列变成2.   也就是说多出的abs(X-Y)次操作可以管也可以不管前面的差分,所以答案就是abs(X-Y)+1

 

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int a[100005];
int main()
{
	int n,dif;
	ll totz=0,totf=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if(i>=2){
		dif = a[i]-a[i-1];
		if(dif>0)totz+=dif;
		else totf-=dif;
		}
	}
	printf("%lld\n%lld",max(totz,totf),abs(totz-totf)+1);
	return 0;
}

 

 

 

 

 

 

 

 

 

 

### Increment Decrement Sequence Implementation In programming, an increment-decrement sequence typically refers to operations that involve increasing or decreasing values by a fixed amount iteratively. This concept can be implemented using loops and arithmetic operators. A common way to implement such sequences involves initializing variables with start values and then applying increments or decrements within loop structures: ```cpp // C++ example demonstrating inc/dec sequence #include <iostream> int main() { int value = 0; // Initial value while (value < 5) { // Loop condition std::cout << "Incrementing: " << ++value << '\n'; // Pre-increment operation } while (value > 0) { std::cout << "Decrementing: " << --value << '\n'; // Pre-decrement operation } return 0; } ``` For more complex scenarios involving collections like arrays or vectors, iterator-based approaches provide flexibility when traversing elements forward or backward[^2]: ```cpp std::vector<int> numbers{1, 2, 3, 4}; for(auto it = numbers.begin(); it != numbers.end(); ++it){ *it += 1; // Increment each element via dereferenced iterator } for(auto rit = numbers.rbegin(); rit != numbers.rend(); ++rit){ *rit -= 1; // Decrement from reverse direction similarly } ``` Iterators allow for efficient traversal over container types without exposing underlying data structure details. When working with standard template library containers, iterators offer powerful ways to manipulate sequences through generic algorithms provided by the C++ Standard Library. Regarding specific implementations of `incdec` as mentioned in some contexts, these might refer to specialized functions designed around particular requirements not covered here directly but following similar principles outlined above.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wym_king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值