zoukankan      html  css  js  c++  java
  • [单调队列] poj 2823 Sliding Window

    题意:

    给你n个数和一个k

    把n分成连续的n-k+1个区间

    第一行按顺序输出每一个区间的最小值,第二行是最大值。

    思路:

    单调队列的模板题,这里注意的是插入队尾的时候须要二分加速

    代码:

    #include"stdio.h"
    #include"algorithm"
    #include"string.h"
    #include"iostream"
    #include"queue"
    #include"map"
    #include"vector"
    #include"string"
    #include"cmath"
    using namespace std;
    #define N 2222222
    struct node
    {
        int x,s;
    };
    int cmp(node a,node b)
    {
        return a.s<b.s;
    }
    int cmp1(node a,node b)
    {
        return a.s>b.s;
    }
    node q[N],v[N];
    int finde_max(int l,int r,int k)
    {
        int ans=-1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(q[mid].s>k)
            {
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        return ans;
    }
    int finde_min(int l,int r,int k)
    {
        int ans=-1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(q[mid].s<k)
            {
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        return ans;
    }
    int main()
    {
        int n,k;
        while(scanf("%d%d",&n,&k)!=-1)
        {
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&v[i].s);
                v[i].x=i;
            }
            int head=0,ed=0;
            for(int i=1;i<=k;i++)  q[ed++]=v[i];
            sort(q,q+k,cmp);
            for(int i=k; i<=n; i++)
            {
                if(head>ed) q[++ed]=v[i];         //入队
                else
                {
                    int tep=finde_min(head,ed,v[i].s);
                    if(tep==-1) q[ed=head]=v[i];
                    else q[ed=tep+1]=v[i];
                }
                while(q[head].x+k<=i) head++;     //出队
                printf(i==n?"%d
    ":"%d ",q[head].s);
            }
    
            head=0,ed=0;
            for(int i=1;i<=k;i++)  q[ed++]=v[i];
            sort(q,q+k,cmp1);
            for(int i=k; i<=n; i++)
            {
                if(head>ed) q[++ed]=v[i];         //入队
                else
                {
                    int tep=finde_max(head,ed,v[i].s);
                    if(tep==-1) q[ed=head]=v[i];
                    else q[ed=tep+1]=v[i];
                }
                while(q[head].x+k<=i) head++;     //出队
                printf(i==n?

    "%d ":"%d ",q[head].s); } } return 0; }



  • 相关阅读:
    COGS727 [网络流24题] 太空飞行计划
    Bzoj1692 洛谷P2870 [Usaco2007 Dec]队列变换
    Bzoj1029 [JSOI2007]建筑抢修
    Bzoj3168 [Heoi2013]钙铁锌硒维生素
    Bzoj4566 [Haoi2016]找相同字符
    Bzoj4771 七彩树
    Bzoj2597 [Wc2007]剪刀石头布
    Bzoj4773 负环
    HDU5772 String problem
    Bzoj1324 Exca王者之剑
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7225530.html
Copyright © 2011-2022 走看看