第三大值、第三小值 如此调用$\lfloor \frac{N+1}{2}\rfloor$次

时间:2021-08-29 07:00:01

标题问题大意:由于过于冗长,欠好解释,所以详见原题。

解题思路:这是一道交互题。

对付第一问,很容易解决。由于数列严格递增,所以不会呈现相等的情况。

首先挪用MinMax(0,10^18,&l,&r)求出最小值和最大值,然后每次挪用MinMax(l+1,r-1,&l,&r)求出次大值、次小值,第三大值、第三小值……

如此挪用$\lfloor \frac{N+1}{2}\rfloor$次,就可以求出整个数组。然后求值即可。

对付第二问,首先仍然是求出最小值min和最大值max。

然后,可以知道[min,max]之间还有N-2个数,那么中间就被分为了N-1份。

按照抽屉道理可知,两数之间的最大间隔至少为$\lceil \frac{a_N - a_1}{N-1}\rceil$,设其为p。

那么我们就将查找区间分为N-1份,每次查找的区间巨细都为p(最后一个区间除外),然后每次用当前盘问到的最小值减去上次盘问到的最大值(跳过-1),得出的答案进行对照,最大的阿谁就是答案。

由于最大间隔至少为p,所以最大间隔必然在两个差别区间中,因此这样做能得到正确的答案。

m的值:第一次挪用N+1,,之后N-1次挪用,总共包罗不赶过N个点,所以$m\leq N+1+N+N-1$,即$m\leq 3N$,切合条件。

然后即可AC。

C++ Code:

#include"gap.h" #define ll long long ll p[100005]; ll findGap(int T,int N){ if(T==1){ int l=1,r=N; ll LL=0,RR=1000000000000000000; while(l<=r){ ll xx,yy; MinMax(LL,RR,&xx,&yy); p[l++]=xx,p[r--]=yy; LL=xx+1,RR=yy-1; } ll max=0; for(int i=1;i<N;++i) if(p[i+1]-p[i]>max)max=p[i+1]-p[i]; return max; }else{ ll xx,yy; MinMax(0,1000000000000000000,&xx,&yy); ll k=(yy-xx)/(N-1); if((yy-xx)%(N-1))++k; ll prer=xx,max=0,nowl,nowr; for(ll l=xx+1;l<yy;l+=k){ ll r=l+k-1; if(r>yy)r=yy-1; MinMax(l,r,&nowl,&nowr); if(nowl-prer>max)max=nowl-prer; if(nowr!=-1) prer=nowr; } if(yy-prer>max)max=yy-prer; return max; } }