zoukankan      html  css  js  c++  java
  • P1440 求m区间内的最小值

    题目描述

    一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。

    输入输出格式

    输入格式:

    第一行两个数n,m。

    第二行,n个正整数,为所给定的数列。

    输出格式:

    n行,第i行的一个数ai,为所求序列中第i个数前m个数的最小值。

    输入输出样例

    输入样例1:

    6 2
    7 8 1 4 3 2

    输出样例1:

    0
    7
    7
    1
    1
    3 

    说明

    【数据规模】

    m≤n≤2000000

    ai<=3*107

    思路:

      单调队列,首先我们要明确一件事情,就是对于i与j来说,如果i<=j,那么a[j]对单调队列的贡献一定比a[i]的贡献大,也就是说,如果当a[i]与a[j]同时存在时,我们一定会选择a[j]。那么我们就可以保证在当前队列中的元素一定是最优的,之后我们再维护一下每一项的时间即可。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    
    using namespace std;
    
    static int n,m;
    
    struct Mt{
        int dis;
        int pos;
    };
    
    Mt mt[2000008];
    
    deque < Mt > q;
    
    long long read()
    {
        long long x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;++i)
        {
            mt[i].dis=read();
            mt[i].pos=i;
        }
        printf("0
    ");
        for(int i=1;i<n;++i)
        {
            while(!q.empty()&&q.back().dis>=mt[i].dis) q.pop_back();//维护单调性 
            q.push_back(mt[i]);//加入元素 
            while(q.front().pos<=i-m) q.pop_front();//删除在区间外的元素 
            printf("%d
    ",q.front().dis);//输出,操作保证了队列的最优性 
        }
        return 0;
    }
  • 相关阅读:
    python 之 re模块、hashlib模块
    python 之 random 模块、 shutil 模块、shelve模块、 xml模块
    python 之 time模块、datetime模块(打印进度条)
    python 之 包的使用
    python 之 序列化与反序列化、os模块
    SAP GUI 750 安装包 及 补丁3 共享
    实例:关于ALV控件可编辑的整理
    SAP 文本框实例
    SAP 日志管理
    TO_DATS() AS ABAP_DATE
  • 原文地址:https://www.cnblogs.com/-hhs/p/11106573.html
Copyright © 2011-2022 走看看