#include <stdio.h>
int main()
{
puts("转载请注明出处谢谢");
puts("http://blog.csdn.net/vmurder/article/details/42970501");
}
题意:自己去看
题解:
我们把平均数序列看成一个线段,那么这个线段就被序列中的数分成了若干段。
然后在其中一段上选一个点,原序列应该是唯一的,
【对应点:当前点+对应点/2=平均数序列中两段交界点】
所以它到下一段的对应点就是唯一的,而此时我们不妨把整个序列沿着当前段和下一段的交界点折一下,
这样当前选的这个点直接平移到折完后的那部分就是它的对应点了~
然后我们就可以把整个序列折来折去,最后它变成一段段的区间,取下交集。
代码中l、r是交集的左右边界,
L、R是当前区间。
注意无解的情况。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 5001000
#define inf 0x3f3f3f3f
using namespace std;
int n,l,r;
int s[N];
int main()
{
// freopen("test.in","r",stdin);
int i,j,k;
scanf("%d%d%d",&n,&s[1],&s[2]);
int L=l=s[1],R=r=s[2];
for(i=3;i<=n;i++)
{
scanf("%d",&s[i]);
k=s[i]-s[i-1];
if(i&1)
{
L=R-k;
l=max(l,L);
}
else
{
R=L+k;
r=min(r,R);
}
}
printf("%d\n",r-l+1>=0?(r-l+1):0);
return 0;
}