【APIO2016】uoj206 Gap

来源:互联网 发布:九阴真经捏脸数据 明星 编辑:程序博客网 时间:2024/06/06 05:37

首先需要注意,满足子任务二的解法并不一定能满足子任务一,所以这两个问题是需要分开处理的。
对于子任务一可以采用从两边逼近的方法,每次询问MinMax(mn+1,mx-1,&mn,&mx),获得首尾两个元素。
对于子任务二,首先找到最大值和最小值,然后把这段区间均分成n1分,记长度下取整为l,那么答案一定不会比l小,否则就拼不起来整个区间了。换句话说,我们把区间每l分成一段,答案一定不会在某一段内部。这样我们对每一段都询问一次,算上最开始的一次,询问次数大概是2n

#include "gap.h"#include<algorithm>using namespace std;#define LL long longconst 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;    }}
0 0