题意:给定一个序列,可以对一个区间进行加1或减1的操作,问最少需要多少次可以将序列的值一样.
Solution
我们将序列差分,得到一个差分数组。
对于每一个区间操作,我们可以把它转化为在查分数组上某个位置+1,某个位置-1,范围1-n+1。
目标是除了第一个数之外其他数都为零(这样所有前缀和都相等,满足所有数字都一样的条件)。
(既然不管第一个数,那我们干脆从2开始差分就好了。)
那我们把正数和负数对着消,最后会剩下一些数。
对于这些数,我们有两种选择,一个是和一消,一个是和n+1消。
所以次数是max(正查分和,负差分和)种类数就是(abs(正查分和-负差分和)+1)
Code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #define N 100002 using namespace std; typedef long long ll; ll a[N],ans1,ans2,ans3; int n; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%lld",&a[i]); for(int i=2;i<=n;++i){ ll c=a[i]-a[i-1]; if(c>0)ans1+=c; else ans2-=c; } ans3=max(ans1,ans2); printf("%lld %lld",ans3,abs(ans1-ans2)+1); return 0; }