PHP短視頻系統單調隊列:ACwing滑動窗口

三種解題代碼:
Rmq:ACwing 上可以

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6;
ll n,m;
ll dma[maxn][10],dmi[maxn][10];
ll a[maxn];
void init()
{
    for(ll i=1; i<=n; i++)
    {
        dma[i][0]=dmi[i][0]=a[i];
    }
    for(ll j=1; (1<<j)<=m; j++)
    {
        for(ll i=1; i+(1<<j)-1<=n; i++)
        {
            dma[i][j]=max(dma[i][j-1],dma[i+(1<<(j-1))][j-1]);
            dmi[i][j]=min(dmi[i][j-1],dmi[i+(1<<(j-1))][j-1]);
        }
    }
}
ll rmq_max(ll l,ll r)
{
    ll k=log2(r-l+1);
    return max(dma[l][k],dma[r-(1<<k)+1][k]);

}
ll rmq_min(ll l,ll r)
{
    ll k=log2(r-l+1);
    return min(dmi[l][k],dmi[r-(1<<k)+1][k]);
}
int main()
{
    scanf("%lld %lld",&n,&m);
    for(ll i=1; i<=n; i++)
    {
        scanf("%lld",&a[i]);
    }
    init();
    for(ll i=1; m+i-1<=n; i++)
    {
        if(i+m-1!=n)
            printf("%lld ",rmq_min(i,m+i-1));
        else
        {
            printf("%lld\n",rmq_min(i,m+i-1));
        }
    }
    for(ll i=1; m+i-1<=n;i++)
    {
        if(i+m-1!=n)
            printf("%lld ",rmq_max(i,m+i-1));
        else
        {
            printf("%lld\n",rmq_max(i,m+i-1));
        }
    }
}

線段樹:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e6+5;
int a[maxn];
struct node
{
    int l,r,maxx,minx;
}tr[maxn*4];
void pushup(int k)
{
    tr[k].maxx=max(tr[k<<1].maxx,tr[k<<1|1].maxx);
    tr[k].minx=min(tr[k<<1].minx,tr[k<<1|1].minx);
}
void build(int k,int l,int r)
{
    tr[k].l=l,tr[k].r=r;
    if(l==r)
    {
        tr[k].minx=tr[k].maxx=a[l];
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    pushup(k);
}
int query_m(int k,int l,int r)
{
    if(tr[k].l>=l&&tr[k].r<=r)
    {
        return tr[k].maxx;
    }
    int mid=tr[k].l+tr[k].r>>1;
    if(mid>=r)
    {
        return query_m(k<<1,l,r);
    }
    else if(mid<l)
    {
        return query_m(k<<1|1,l,r);
    }
    return max(query_m(k<<1,l,mid),query_m(k<<1|1,mid+1,r));
}
int query_mi(int k,int l,int r)
{
    if(tr[k].l>=l&&tr[k].r<=r)
    {
        return tr[k].minx;
    }
    int mid=tr[k].l+tr[k].r>>1;
    if(mid>=r)
    {
        return query_mi(k<<1,l,r);
    }
    else if(mid<l)
    {
        return query_mi(k<<1|1,l,r);
    }
    return min(query_mi(k<<1,l,mid),query_mi(k<<1|1,mid+1,r));
}
int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    build(1,1,n);
    for(int i=1;i+k-1<=n;i++)
    {
        if(i+k-1!=n)
        {
            printf("%d ",query_mi(1,i,i+k-1));
        }
        else
        {
            printf("%d\n",query_mi(1,i,i+k-1));
        }
    }
    for(int i=1;i+k-1<=n;i++)
    {
        if(i+k-1!=n)
        {
            printf("%d ",query_m(1,i,i+k-1));
        }
        else
        {
            printf("%d\n",query_m(1,i,i+k-1));
        }
    }
}

單調隊列:

#include<bits/stdc++.h>
using namespace std;
//單調隊列
const int maxn=1e6+5;
int q[maxn],a[maxn];
int n,k;
void solv()
{
    int head=0,tail=-1;
    for(int i=0;i<n;i++)
    {
        if(head<=tail&&i-q[head]>=k)
            head++;
        while(head<=tail&&a[q[tail]]>a[i])
            tail--;
        q[++tail]=i;
        if(i-k+1>=0)
            cout<<a[q[head]]<<' ';
    }
    cout<<endl;
    head=0,tail=-1;
    for(int i=0;i<n;i++)
    {
        if(head<=tail&&i-q[head]>=k)
            head++;
        while(head<=tail&&a[q[tail]]<a[i])
            tail--;
        q[++tail]=i;
        if(i-k+1>=0)
            cout<<a[q[head]]<<' ';
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>k;
    for(int i=0;i<n;i++)
        cin>>a[i];
    solv();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章