码迷,mamicode.com
首页 > 其他好文 > 详细

洛谷1440 求m区间内的最小值

时间:2015-10-21 20:44:48      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

洛谷1440 求m区间内的最小值

本题地址: http://www.luogu.org/problem/show?pid=1440

题目描述

一个含有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

 

 

【思路】

   单调队列。

   题目比较裸,直接用一个单调队列维护即可。单调队列第一次写,总结有如下需要注意的地方:

1、   注意维护的是什么,本题中维护的是一个满足序号 >=i-m+1 的序列,其中序列满足a值单调递增。

2、   注意边界,特别是初始情况下是否满足平凡情况。

3、   注意单调队列的维护添加 与取值之间的顺序,取决于使用单调队列的目的。

 

   还有需要注意的是题目中要求i之前m个,每次取值是算上当前a的所以需要错开一个。

 

【代码】

 

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 
 5 const int maxn = 2000000+10;
 6 
 7 int a[maxn],que[maxn],d[maxn];
 8 int n,m,front,rear;
 9 
10 inline int read_int() {
11     char c; c=getchar();
12     while(!isdigit(c)) c=getchar();
13     
14     int x=0;
15     while(isdigit(c)) {
16         x=x*10+c-0;
17         c=getchar();
18     }
19     return x;
20 }
21 
22 int main() {
23     n=read_int(); m=read_int();
24     a[0]=1<<30;               //边界不取 
25     front=rear=1;
26     for(int i=1;i<=n;i++)
27     {
28         a[i]=read_int();
29         
30         //注意顺序 
31         while(front<=rear && (que[front]<(i-m+1))) front++;
32            
33         while(front<=rear && a[i]<=a[que[rear]]) rear--;  //注意维护a值最小的 
34         
35         que[++rear]=i;
36 
37         d[i]=a[que[front]];
38         
39     }
40     cout<<0<<"\n";
41     for(int i=1;i<n;i++) cout<<d[i]<<"\n";
42     return 0;
43 }

 

洛谷1440 求m区间内的最小值

标签:

原文地址:http://www.cnblogs.com/lidaxin/p/4898722.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!