题目情境#
题目链接:https://www.luogu.com.cn/problem/P4552 ↗
题目描述
给定一个长度为 的数列 ,每次可以选择一个区间,使这个区间内的数都加 或者都减 。
请问至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列有多少种。
输入格式
第一行一个正整数
接下来 行,每行一个整数,第 行的整数表示 。
输出格式
第一行输出最少操作次数
第二行输出最终能得到多少种结果
输入输出样例
输入 #1
4
1
1
2
2plaintext输出 #1
1
2plaintext对于 的数据,。
算法解析#
差分思想
把序列 的区间 加 ,等价于其差分序列 的点 加 ,点 减 ,其他位置不变。
即把原序列的“区间操作”转化为差分序列的“两点操作”。多次区间操作完成后,再利用前缀和还原。
时间复杂度从 降为 。
示例: : 1 2 3 1 2 3 : 1 1 1 -2 1 1
Python代码实现#
n = int(input())
a = [0]
b = [0] * (n + 1)
for i in range(1, n + 1):
a.append(int(input()))
b[i] = a[i] - a[i - 1]
p, q = 0, 0
for i in range(2, n + 1):
if b[i] > 0:
p += b[i]
else:
q += abs(b[i])
print(max(p, q))
print(abs(p - q) + 1)pythonC++代码实现#
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N=100010;
int a[N], b[N];
int main(){
int n;
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++) b[i]=a[i]-a[i-1];
LL p=0, q=0;
for(int i=2; i<=n; i++)
if(b[i]>0) p+=b[i];
else q+=abs(b[i]);
cout<<max(p,q)<<'\n'<<abs(p-q)+1;
}c