【APIO2016】Gap
交互题
对于30%的数据,直接从s=0,t=1e18开始,每次让s=mn+1,t=mx-1,每一次可以得到两个,可以在(n+1)/2的时间内得到
对于其他数据,我们先求出最大最小值,求出len=(mx-mn)/(n-1),这相当与是一个"平均数",如果我将区间分为若干段长度为len的区间,只记录每个区间内的最大值和最小值,这样被漏算的那些点,他们最多有len-1的贡献,而这个还达不到平均数,所以肯定不会影响答案,所以就可以在3*n以内求出序列有用的部分了。
恰的很紧,稍不注意可能就过不去某些点,我之前区间长度设的是len-1,会被极限数据卡掉。
1 #include "gap.h" 2 #define LL long long 3 const LL inf=1e18; 4 5 LL max(LL x,LL y){ 6 return x>y?x:y; 7 } 8 LL min(LL x,LL y){ 9 return x<y?x:y; 10 } 11 long long findGap(int T, int N) 12 { 13 LL mn,mx; 14 LL ans=-inf; 15 LL s=0,t=inf,a[100005],cnt; 16 if(T==1){ 17 for(int i=1;i<=(N+1)/2;i++){ 18 MinMax(s,t,&mn,&mx); 19 s=mn+1;t=mx-1; 20 a[i]=mn;a[N-i+1]=mx; 21 } 22 for(int i=2;i<=N;i++)ans=max(ans,a[i]-a[i-1]); 23 } 24 else { 25 MinMax(s,t,&mn,&mx); 26 LL len=(mx-mn)/(N-1),Max=mx; 27 a[++cnt]=mn; 28 for(LL l=mn+1,r=l+len;l<=Max;l=r+1,r=l+len){ 29 MinMax(l,min(r,Max),&mn,&mx); 30 if(mn!=-1){ 31 a[++cnt]=mn; 32 if(mn!=mx)a[++cnt]=mx; 33 } 34 } 35 for(int i=2;i<=cnt;i++)ans=max(ans,a[i]-a[i-1]); 36 } 37 return ans; 38 }