zoukankan      html  css  js  c++  java
  • POJ2823:Sliding Window

    传送门

    题意

    有一个数列a,要求你求数列b和c,b[i]是a[i]…a[i+w-1]中的最小值,c[i]是最大值。如果a是1,3,-1,-3,5,3,6,7,则b为-1,-3,-3,-3,3,3,c为3,3,5,5,6,7。

    分析

    单调队列裸题,不过第一次写单调队列发现了很多trick

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define F(i,a,b) for(int i=a;i<=b;++i)
    #define R(i,a,b) for(int i=a;i<b;++i)
    #define mem(a,b) memset(a,b,sizeof(a))
    #pragma comment(linker, "/STACK:102400000,102400000")
    inline void read(int &x){x=0; char ch=getchar();while(ch<'0') ch=getchar();while(ch>='0'){x=x*10+ch-48; ch=getchar();}}
    
    int a[1001000],n,k,l,r,b[1001000];
    pair<int,int>q[1001000];//1
    int main()
    {
        //freopen("data.in","r",stdin);
        //freopen("wa.out","w",stdout);
        while(scanf("%d %d",&n,&k)==2)
        {
            R(i,0,n) scanf("%d",a+i);
            l=r=0;
            q[r++]=make_pair(0,a[0]);
            R(i,1,k)
            {
                while(r&&a[i]<=q[r-1].second) r--;//2
                q[r++]=make_pair(i,a[i]);
            }
            b[1]=q[l].second;
            R(i,k,n)
            {
                while(r&&a[i]<=q[r-1].second) r--;
                l=min(l,r);//3
                q[r++]=make_pair(i,a[i]);
                while(i-k>q[l].first-1) l++;//4
                //printf("l=%d r=%d
    ",l,r);
                b[i-k+2]=q[l].second;
            }
           // R(i,0,r) printf("%d%c",q[i].second,i==r-1?'
    ':' ');
            F(i,1,n-k+1) printf("%d%c",b[i],i==n-k+1?'
    ':' ');
            l=r=0;
            q[r++]=make_pair(0,a[0]);
            R(i,1,k)
            {
                while(r&&a[i]>=q[r-1].second) r--;
                q[r++]=make_pair(i,a[i]);
            }
            b[1]=q[l].second;
            R(i,k,n)
            {
                while(r&&a[i]>=q[r-1].second) r--;
                l=min(l,r);
                q[r++]=make_pair(i,a[i]);
                while(i-k>q[l].first-1) l++;
               // printf("l=%d r=%d
    ",l,r);
                b[i-k+2]=q[l].second;
            }
            F(i,1,n-k+1) printf("%d%c",b[i],i==n-k+1?'
    ':' ');
        }
        return 0;
    }
    /*
    1.用pair记录每个放入队列的数的下标和值
    2.从后往前找插入的位置,顺便删除后面的元素
    3.更新左端点l
    4.如果左端点的下标小于区域左端点,更逊左端点
    */
    
  • 相关阅读:
    第三次作业
    最后一次作业
    第14.15周作业
    第七周作业
    第六周作业
    第四周作业
    第三周作业
    第二周作业
    第一周作业
    第0次作业
  • 原文地址:https://www.cnblogs.com/chendl111/p/6554099.html
Copyright © 2011-2022 走看看