#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; }
时间: 2024-11-08 21:10:49