首先需要注意,满足子任务二的解法并不一定能满足子任务一,所以这两个问题是需要分开处理的。
对于子任务一可以采用从两边逼近的方法,每次询问MinMax(mn+1,mx-1,&mn,&mx),获得首尾两个元素。
对于子任务二,首先找到最大值和最小值,然后把这段区间均分成
n−1
分,记长度下取整为
l
,那么答案一定不会比
#include "gap.h"
#include<algorithm>
using namespace std;
#define LL long long
const LL oo=1e18;
const int maxn=200010;
LL a[maxn];
long long findGap(int T, int N)
{
if (T==1)
{
LL ans=0,mn=-1,mx=oo+1;
for (int i=1,j=N;i<=j;i++,j--)
{
MinMax(mn+1,mx-1,&mn,&mx);
a[i]=mn;
a[j]=mx;
}
for (int i=1;i<N;i++) ans=max(ans,a[i+1]-a[i]);
return ans;
}
else
{
int n=1;
LL mn,mx,l,p,ans=0,L,R;
MinMax(0,oo,&L,&R);
l=(R-L+N-2)/(N-1);
a[1]=p=L;
for (LL i=L+1;i+l-1<R;i+=l)
{
MinMax(i,p=i+l-1,&mn,&mx);
if (mn==-1) continue;
a[++n]=mn;
a[++n]=mx;
}
if (p<R-1)
{
MinMax(p+1,R-1,&mn,&mx);
if (mn!=-1)
{
a[++n]=mn;
a[++n]=mx;
}
}
a[++n]=R;
for (int i=1;i<n;i++) ans=max(ans,a[i+1]-a[i]);
return ans;
}
}