题意
有 N 个严格递增的非负整数 a1,a2,…,aN(0≤a1 < a2 < ⋯ < aN≤10^18)。你需要找出 ai+1−ai(0≤i≤N−1)里的最大的值。
你的程序不能直接读入这个整数序列,但是你可以通过给定的函数来查询该序列的信息。关于查询函数的细节,请根据你所使用的语言,参考下面的实现细节部分。
对于子任务1,每次调用M+1
对于子任务2,每次调用假设区间内有k个整数,M+=k+1
分析
首先对于子任务1还是很简单的,每次找两个,不断缩小范围
对于子任务2考虑分治的方法?,考虑到只要找最大值,那么把最前面的和最后面的找出来,中间的答案至少有 这么大, 那么我们以这个间隔来跳,最多跳n个区间,然后最多找到n个数,所以有3n做法
代码
#include <bits/stdc++.h>
#include "gap.h"
using namespace std;
#define pb push_back
typedef long long ll;
const ll inf = 1e18;
ll a[100010];
ll findGap(int T, int N)
{
vector<ll> v;
if(T==1)
{
ll ml = 1; ll mr = N; a[0] = -1; a[N+1] = inf+1;
while(ml <= mr)
{
ll mn , mx;
MinMax(a[ml-1] + 1, a[mr+1] - 1, &a[ml], &a[mr]);
ml++; mr--;
}
ll ans = 0;
for(ll i=2;i<=N;i++) ans = max(a[i] - a[i-1] , ans);
return ans;
}
else
{
ll s,t; MinMax(0,inf,&s,&t);
ll delta = (t-s) / (N-1); ll ans = delta;
ll x=s;
for(ll i=s+1;i<=t;i+=delta+1)
{
ll mn , mx;
MinMax(i,i+delta,&mn,&mx);
if(mn!=-1) ans = max(ans , mn - x) , x = mx;
}
return ans;
}
return 0;
}
/*#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
static void my_assert(int k){ if (!k) exit(1); }
static int subtask_num, N;
static long long A[100001];
static long long call_count;
void MinMax(long long s, long long t, long long *mn, long long *mx)
{
int lo = 1, hi = N, left = N+1, right = 0;
my_assert(s <= t && mn != NULL && mx != NULL);
while (lo <= hi){
int mid = (lo+hi)>>1;
if (A[mid] >= s) hi = mid - 1, left = mid;
else lo = mid + 1;
}
lo = 1, hi = N;
while (lo <= hi){
int mid = (lo+hi)>>1;
if (A[mid] <= t) lo = mid + 1, right = mid;
else hi = mid - 1;
}
if (left > right) *mn = *mx = -1;
else{
*mn = A[left];
*mx = A[right];
}
if (subtask_num == 1) call_count++;
else if (subtask_num == 2) call_count += right-left+2;
}
const ll inf = 1e18;
ll a[100010];
ll findGap(int T, int N)
{
vector<ll> v;
if(T==1)
{
ll ml = 1; ll mr = N; a[0] = -1; a[N+1] = inf+1;
while(ml <= mr)
{
ll mn , mx;
MinMax(a[ml-1] + 1, a[mr+1] - 1, &a[ml], &a[mr]);
ml++; mr--;
}
ll ans = 0;
for(ll i=2;i<=N;i++) ans = max(a[i] - a[i-1] , ans);
return ans;
}
else
{
ll s,t; MinMax(0,inf,&s,&t);
ll delta = (t-s) / (N-1); ll ans = delta;
ll x=s;
for(ll i=s+1;i<=t;i+=delta)
{
ll mn , mx;
MinMax(i,i+delta,&mn,&mx);
if(mn!=-1) ans = max(ans , mn - x) , x = mx;
}
return ans;
}
return 0;
}
int main()
{
// FILE *in = stdin, *out = stdout;
freopen("gap.in","r",stdin);
scanf("%d%d", &subtask_num, &N);
for (int i=1;i<=N;i++) scanf("%lld", A+i);
printf("%lld\n", findGap(subtask_num, N));
printf("%lld\n", call_count);
}
*/