[ABC_352_d] 题解

题意

在长为 \(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;
}
posted @ 2024-06-27 11:48  merlinkkk  阅读(30)  评论(0)    收藏  举报