luogu 1440 求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

ai3×10^7

分析

单调队列

单调队列内部单调递增

代码

 1 /**************************
 2 User:Mandy.H.Y
 3 Language:c++
 4 Problem:luogu1440
 5 Algorithm:
 6 **************************/
 7 #include<bits/stdc++.h>
 8 
 9 using namespace std;
10 
11 const int maxn = 2e6 + 5;
12 
13 int n,l,r,m;
14 int q[maxn],a[maxn];
15 
16 template<class T>inline void read(T &x){
17     x = 0;bool flag = 0;char ch = getchar();
18     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
19     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
20     if(flag) x = -x;
21 }
22 
23 template<class T>void putch(const T x){
24     if(x > 9) putch(x / 10);
25     putchar(x % 10 | 48);
26 }
27 
28 template<class T>void put(const T x){
29     if(x < 0) putchar('-'),putch(-x);
30     else putch(x);
31 }
32 
33 void file(){
34     freopen("1440.in","r",stdin);
35     freopen("1440.out","w",stdout);
36 }
37 
38 void readdata(){
39     read(n);read(m);
40 }
41 
42 void work(){
43     for(int i = 1;i <= n; ++ i){
44         
45         read(a[i]);
46         
47         while(l < r && i - q[l] > m) l++;
48         
49         if(l >= r) puts("0");
50         else put(a[q[l]]),putchar('
');
51         
52         while(l < r && a[q[r - 1]] >= a[i]) r--;//>= 
53         q[r++] = i;
54     }
55 }
56 
57 int main(){
58 //    file();
59     readdata();
60     work();
61     return 0;
62 }
View Code
非做顽石不可,哪管他敬仰暗唾
原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11417077.html