#2T 90pts 求卡常

P1886 滑动窗口 /【模板】单调队列

Wildchesse @ 2023-08-12 17:10:47

用了两个堆,时间复杂度O(nlgn)但T在第二个点,悬关求卡常

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define MAXN 1000005
using namespace std;
struct node{
    int pos,val;
    bool operator<(const node &x)const{
        return val>x.val;
    }
    bool operator>(const node &x)const{
        return val<x.val;
    }
}a[MAXN];
int n,k,num=n-k+1,mi[MAXN],ma[MAXN],tag=1;
priority_queue<node> q1;
priority_queue<node,vector<node>,greater<node> > q2;
signed main(){
//  ios::sync_with_stdio(false);
//  cin.tie(NULL);
//  cout.tie(NULL);
    cin>>n>>k;
    num=n-k+1;
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i].val);
        a[i].pos=i;
    }
    for(int i=1;i<=k;i++){
        q1.push(a[i]);
        q2.push(a[i]);
    }
    for(int i=1;i<=num;i++){
        while(q1.top().pos<tag){
            q1.pop();
        }
        while(q2.top().pos<tag){
            q2.pop();
        }
        mi[i]=q1.top().val;
        ma[i]=q2.top().val;
        q1.push(a[k+i]);
        q2.push(a[k+i]);
        tag++;
    }
    for(int i=1;i<=num;i++){
        printf("%lld ",mi[i]);
    }
    cout<<endl;
    for(int i=1;i<=num;i++){
        printf("%lld ",ma[i]);
    }
    return 0;
}

by Li_wc0802 @ 2023-08-16 09:16:50

你可以这么写

#include<iostream>
using namespace std;
int p[1000001];
int q[1000001],head=1,tail,n,a[1000001],k;
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    q[0]=-999999999;
    for(int i=1;i<=n;i++)
    {
        while(a[i]<q[tail]&&head<=tail)tail--;
        q[++tail]=a[i];
        p[tail]=i;
        while(i-k+1>p[head])head++;
        if(i>=k)cout<<q[head]<<' ';
    }
    cout<<endl;
    head=1,tail=0;
    q[0]=99999999;
    for(int i=1;i<=n;i++)
    {
        while(a[i]>q[tail]&&head<=tail)tail--;
        q[++tail]=a[i];
        p[tail]=i;
        while(i-k+1>p[head])head++;
        if(i>=k)cout<<q[head]<<' ';
    }
    return 0;
}

希望有帮助


by Li_wc0802 @ 2023-08-16 09:22:12

@Wildchesse 因为你只需要让队首最小,然后在弹出就可以了,这是最小值;最大值复制一下稍作修改就可以


by Li_wc0802 @ 2023-08-16 09:24:39

@Wildchesse 我代码有点乱,你凑合这看一下吧,总之就是弄一下队首就可以了


by Wildchesse @ 2023-08-16 09:44:09

@Li_wc 已关,thx


|