P4552 [Poetize6] IncDec Sequence
提交6.73k
通过3.00k
时间限制1.00s
内存限制128.00MB
提交答案加入题单
题目提供者yyy2015c01嘤嘤嘤
难度普及+/提高
历史分数100
标签
查看算法标签
相关讨论
查看讨论
推荐题目
查看推荐
洛谷推荐关闭
展开
题目描述
给定一个长度为 nn 的数列 {a_1,a_2,\cdots,a_n}a1,a2,⋯,an,每次可以选择一个区间[l,r][l,r],使这个区间内的数都加 11 或者都减 11。
请问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。
输入格式
第一行一个正整数 nn
接下来 nn 行,每行一个整数,第 i+1i+1行的整数表示 a_iai。
输出格式
第一行输出最少操作次数
第二行输出最终能得到多少种结果
输入输出样例
输入 #1复制
4 1 1 2 2
输出 #1复制
1 2
说明/提示
对于 100\%100% 的数据,n\le 100000, 0 \le a_i \le 2^{31}n≤100000,0≤ai≤231。
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <iostream>
#include<stack>
#include<cstdlib>
#include<map>
#pragma warning(disable:4996)
using namespace std;
typedef long long ll;
//总结,运用差分
//本题核心在于 导出差分数组
//然后问题就是 用最少步骤把差分数组的每一项变成0
//最小步数的答案通过推导得出 min(p,q) + abs(p-q)
//种类取决于差分数组 b[1] 有几种 b[1] 就有几个答案
//通过推导 答案是 abs(p-q)+1 //+1是自身本来就有的
int a[100005];
int b[100005];
int main()
{
int n = 0;
cin >> n;
int i = 0;
ll q = 0;//和可能爆int
ll p = 0;
for (i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i] - a[i - 1];//差分
if (i >= 2)
{
if (b[i] < 0)
{
p -= b[i];//负数绝对值
}
if (b[i] > 0)
{
q += b[i];//正数
}
}
}
cout << min(q, p) + abs(p - q) << endl << abs(p - q)+1;
return 0;
}