Suffix Operations Codeforces Round #688 (Div. 2)B

http://codeforces.com/contest/1453/problem/B
题意:通过对后缀数组的+1-1使数全部相等,开始前你可以直接修改一个数的值,问最小操作数

思路:

差分约束,先不考虑修改数。首先,获取相邻数的差我们设为Si(Si=a[i]-a[i-1],2<=i<=n),假设我们改的后缀数组从j(1<j<=n)开始,那么由于同时更改,j-n的数之间差不变,只改变了j-1和j的数的差,而最终状态我们要使所有的差归零,也就是说要的操作数就是所有差的绝对值之和。
现在考虑,改一个数:
改开头和结尾,可以使S2,Sn归零
改中间,位置设为j(1<j<n):Sj,S(j+1)同增同减:同号没影响;异号操作数减少绝对值小的一个数的两倍
(如-3 -5 -2 ,差是 -2 3,把-5改成-3,差变为0 1,操作数减少4)
最后答案减去改的数减小的操作数就行了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int a[N],sub[N];
int main() {
 int t;
 cin>>t;
 while(t--){
 int n;
 cin>>n;
 for(int i=1;i<=n;i++){
  cin>>a[i];
  if(i>1)
  sub[i]=a[i]-a[i-1];
 }
 ll x=0,y=0;
 ll maxx=0;
 for(int i=2;i<=n;i++){
  if(sub[i]<0)x-=sub[i];
  else y+=sub[i];
  if(i!=n){
   if((sub[i]>0&&sub[i+1]>0)||(sub[i]<0&&sub[i+1]<0))continue;
   ll k=min(abs(sub[i]),abs(sub[i+1]));
   if(k>maxx)maxx=k;
  }
 }
 maxx=2*maxx;
 if(abs(sub[n])>maxx)maxx=abs(sub[n]);
 if(abs(sub[2])>maxx)maxx=abs(sub[2]);
// cout<<x<<" "<<y<<" "<<maxx<<endl;
 cout<<x+y-maxx<<endl;
 }
 } 
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页