题意
在长为 \(n\) 的序列 \(a\) 中 找出 \(k\) 个数,设它们的下表为 $p_1 \(,\)p_2$ 到 \(p_k\),满足这 \(k\) 个数从小到大排列过后是一个公差为 \(1\) 的等差数列。求满足条件的 \(k\) 个数的最大的 \(p\) 减去 最小的 \(p\) 最小。输出这个值。
思路
把数组 \(a\) 排一遍序,滑动窗口维护最大和最小的 \(p_i\) 旧行了。
代码
#include <bits/stdc++.h>
using namespace std;
pair<int, int> b[200010];
int a[200010];
int p1[200010], p2[200010];
signed main()
{
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
cin >> b[i].first;
b[i].second = i;
}
sort(b + 1, b + n + 1);
for (int i = 1; i <= n; i++)
a[i] = b[i].second;
deque<int> q;
for (int i = 1; i <= n; i++)
{
while (!q.empty() && a[q.back()] > a[i])
q.pop_back();
q.push_back(i);
if (i >= k)
{
while (!q.empty() && q.front() <= i - k)
q.pop_front();
p1[i] = a[q.front()];
}
}
while (!q.empty())
q.pop_back();
for (int i = 1; i <= n; i++)
{
while (!q.empty() && a[q.back()] < a[i])
q.pop_back();
q.push_back(i);
if (i >= k)
{
while (!q.empty() && q.front() <= i - k)
q.pop_front();
p2[i] = a[q.front()];
}
}
int ans = 0x3f3f3f3f;
for (int i = k; i <= n; i++)
{
ans = min(p2[i] - p1[i], ans);
}
cout << ans;
return 0;
}
标签:ABC352D,int,题解,个数,200010,front,empty
From: https://www.cnblogs.com/merlinkkk/p/18306113