题解 P3641 【[APIO2016]最大差分】
这题我UOJ上AC了,来洛谷发题解是为了水社区分。
uoj#206
子任务1(30分)
就是送的啊,会读题就会做。
先
这样问
子任务2(70分)
我们这次还是先问出
这时答案最小是
那么我们就可以把每个块都问一遍,答案只会出现在当前块的最小值和上一个有值的块的最大值。
这样的话,第一次讯问对k的贡献是n+1,中间对k的贡献是
#include "gap.h"
#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
ll a[100011];
long long findGap(int T, int N){
ll ans=0;int n=N;
if (T==1){
a[0]=-1; a[n+1]=1LL*1000000000000000010;
for (int i=1; i<=(n+1)>>1; i++)
MinMax(a[i-1]+1,a[n-i+2]-1,&a[i],&a[n-i+1]);
for (int i=1; i<n; i++)
ans=max(ans,a[i+1]-a[i]);
}
else{
ll minn,maxn,l,r,k,rl,las=-1;
MinMax(0,1LL*1000000000000000000,&minn,&maxn);
k=(maxn-minn)/(n-1); las=minn;
if ((maxn-minn)%(n-1)) k++;
for (ll i=minn+1; i<maxn; i+=k){
rl=min(i+k-1,maxn-1);
MinMax(i,rl,&l,&r);
ans=max(ans,l-las);
if (r>0) las=r;
}
ans=max(ans,maxn-las);
}
return ans;
}