洛谷__P10059 Choose(单调队列+二分)
题目链接:P10059 Choose - 洛谷
题目大意:
在一个序列里选出 个长度为 且位置不同的区间,
要求这 个区间的极差 X 的最小值最大,求在这个最大值 最小的 。
输出 X 和 L
思路:
先直接枚举所有长度为 的区间,求出这些区间的极差最小值 ,第一个答案即为
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#include<array>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/numeric>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
#define gmap __gnu_pbds::gp_hash_table
#define power __gnu_cxx::power
using namespace std;
typedef pair<int, int> pii;
const int N = 200086, mod = 998244353;
int n, m;
int a[N];
int res = inf;
bool check(int mid) {
deque<int> q1, q2;
int cnt = 0;
for (int i = 1; i <= n; i++) {
while (q1.size() && i - q1.front() >= mid) q1.pop_front();
while (q1.size() && a[q1.back()] > a[i]) q1.pop_back();
q1.push_back(i);
while (q2.size() && i - q2.front() >= mid) q2.pop_front();
while (q2.size() && a[q2.back()] < a[i]) q2.pop_back();
q2.push_back(i);
// 统计极差≥res的窗口数量
if (i >= mid && a[q2.front()] - a[q1.front()] >= res) cnt++;
}
return cnt >= m;// 检查是否有至少m个满足条件的窗口
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
int len = n - m + 1;
deque<int> q1, q2;
res = inf;
for (int i = 1; i <= n; i++) {
while (q1.size() && i - q1.front() >= len) q1.pop_front();
while (q1.size() && a[q1.back()] > a[i]) q1.pop_back();
q1.push_back(i);
while (q2.size() && i - q2.front() >= len) q2.pop_front();
while (q2.size() && a[q2.back()] < a[i]) q2.pop_back();
q2.push_back(i);
if (i >= len) res = min(res, a[q2.front()] - a[q1.front()]);
}
int l = 0, r = len + 1;
while (l + 1 < r) {
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid;
}
cout << res << " " << r << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号