首先把序列变成长度
n−1
的差分数列,那么这时的目标是将这个序列的每一个值都变为
0
。将区间操作转化成差分数列上的操作,就有:
1.将任意一个数减去或加上1(此时只要直接对前缀区间或后缀区间操作即可)。
2.将任意两个数进行相反的加减操作(此时只要直接对这个区间进行操作即可)。
设这个数列中小于0的数的和为
对于上面这个构造的过程,可以发现,在消去
B
对数之后,可以到达的数是固定的
ps.把变换后的数列画成阶梯状的图推导就简单很多。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
typedef long long ll;
int n,ct=0;
ll ar[1000010];
void cl(){
int i,j;ll a,b;
scanf("%d",&n);
for(i=1;i<=n;scanf("%I64d",&ar[i++]));
for(i=2,a=b=0;i<=n;++i){
if(ar[i]>ar[i-1])a+=ar[i]-ar[i-1];
else
b+=ar[i-1]-ar[i];
}
if(a<b)swap(a,b);
printf("Case %d: %I64d %I64d\n",++ct,a,a-b+1);
};
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;scanf("%d",&t);
while(t--)cl();
return 0;
};