给定一个长度为 nn 的数列 a1,a2,…,ana1,a2,…,an,每次可以选择一个区间 [l,r][l,r],使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
输入格式
第一行输入正整数 nn。
接下来 nn 行,每行输入一个整数,第 i+1i+1 行的整数代表 aiai。
输出格式
第一行输出最少操作次数。
第二行输出最终能得到多少种结果。
数据范围
0<n≤1050<n≤105,
0≤ai<21474836480≤ai<2147483648
输入样例:
4
1
1
2
2
输出样例:
1
2
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
//我们有四种操作
//2=<i,j<=n 此时我们进行的是整个区间的操作
//i=1, 2=<j<=n
//2=<i<=n,j=n+1;
//i=1;j=n+1 //此时对整个区间进行操作,可以直接减去,整个区间同时加1,同时减1,无用操作
const int N=1e5+10;
ll a[N],b[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i]-a[i-1]; 差分
//题中说,最后每个值都相等,那么由于b[i]=a[i]-a[i-1],除了b[1],因为b[1]=a[1],其他的b全为零
//那么问题就变成如果把b[2]-b[n],变成零的问题
}
//差分数组中,根据贪心的思想,我们可以根据情况1,来找一对正负的数,来确定2个边界,正的加1,负的减1,这样更快的趋于0;
//最后,有可能只剩下正的,或者只剩下负的,如果是零的话答案也就出来了,
//如果只剩下正的,或者只剩下负的,那么我们可以根据2.3的情况,来让这个数和边界进行消除,这样我们的操作次数就是,pos,neg中绝对值
//的最大值pos(所有正数的和),neg为所有负数的和
ll pos=0,neg=0;
for(int i=2;i<=n;i++)
{
if(b[i]>0) pos+=b[i];
else neg-=b[i];
}
cout<<max(pos,neg)<<endl;
//所有种数,就是a[1]有多少中不一样的值,当我们将剩余的正数或者剩余的负数,用3的情况来变成零时,a[1],是不变的,也就是加1
//而当我们用三的情况来变成0时,就是fabs(pos-neg)+1的结果
cout<<abs(pos-neg)+1<<endl;
return 0;
}