考虑二分答案
只要能检验答案能不能小于 x 就行了
令 fi,j 表示一个人在 i 另一个人在 j 是否可行
那么 fi,j=fi−1,j∧|ai−aj|≤x
这东西要set维护下就好了…
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <set>
#include <cmath>
using namespace std;
const int N=100010;
int n,a[N];
set<int> S;
inline bool check(int x){
if(abs(a[1]-a[2])>x) return false;
S.clear(); S.insert(a[1]);
for(int i=3;i<=n;i++){
S.insert(a[i-1]);
while(!S.empty() && abs(*S.begin()-a[i])>x) S.erase(S.begin());
while(!S.empty() && abs(*S.rbegin()-a[i])>x) S.erase(*S.rbegin());
if(S.empty()) return false;
}
return true;
}
int main(){
scanf("%d%d%d",&n,&a[1],&a[2]);
for(int i=3;i<=n+2;i++)
scanf("%d",&a[i]);
n+=2;
int L=0,R=1000000000,mid,ans;
while(L<=R) check(mid=L+R>>1)?R=(ans=mid)-1:L=mid+1;
printf("%d\n",ans);
return 0;
}
二分查找与集合维护

本文介绍了一种利用二分查找结合集合维护的方法来解决特定问题的算法思路。该算法通过检验答案是否可行来逐步缩小查找范围,最终找到符合条件的最大值。在实现过程中使用了集合数据结构来高效地判断两个元素之间的距离是否满足条件。

480

被折叠的 条评论
为什么被折叠?



