Description&Data Constraint
Solution
题外话:去掉了一张图片。
回到题目。题目大意就是给出一个序列 a a a,每次操作可以使得序列 a a a 的一段区间在模 m m m 的意义下 +1 或 -1。求最少操作次数。
如果没有模 m m m 的条件,那么就很简单。直接差分统计 max ( 正 数 和 , ∣ 负 数 和 ∣ ) \max(正数和,|负数和|) max(正数和,∣负数和∣)。
但是在加了模 m m m 的条件后,题目稍稍难了一点。
依旧考虑差分,差分完排序,求出前缀和、后缀和。然后找到一个点令前后缀相等,就是答案。
具体见code,因为讲的不是很清楚。
Code
#include<cstdio>
#include<algorithm>
#define N 1000005
using namespace std;
long long n,m,a[N],c[N],pre[N],suf[N];
int main()
{
freopen("lock.in","r",stdin);
freopen("lock.out","w",stdout);
scanf("%lld%lld",&n,&m);
for (int i=1;i<=n;++i)
scanf("%lld",&a[i]);
for (int i=1;i<=n+1;++i)
c[i]=(a[i]-a[i-1]+m)%m;
sort(c+1,c+1+n+1);
for (int i=1;i<=n+1;++i)
pre[i]=pre[i-1]+c[i];
for (int i=n+1;i;--i)
suf[i]=suf[i+1]-c[i]+m;
for (int i=0;i<=n;++i)
if (pre[i]==suf[i+1]) printf("%lld\n",pre[i]);
return 0;
}