POJ2823 Sliding Window(单调队列)

题目要输出一个序列各个长度k的连续子序列的最大值最小值。

多次RMQ的算法也是能过的,不过单调队列O(n)。

这题,队列存元素值以及元素下标,队尾出队维护单调性然后入队,队首出队保持新元素下标与队首元素下标差小于k。

以前写的还是3个if-else,重写了下。。不加输出挂会T。。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 #define MAXN 1111111
 5 inline void in(int &ret){
 6     char c; int sgn;
 7     while(c=getchar(),c!='-'&&(c<'0'||c>'9')) if(c==EOF) return;
 8     sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0');
 9     while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
10     ret*=sgn;
11 }
12 void out(int x){
13     if(x<0){
14         putchar('-'); out(-x);
15         return;
16     }
17     if(x>9) out(x/10);
18     putchar(x%10+'0');
19 }
20 int que[MAXN],idx[MAXN],front,rear;
21 int a[MAXN];
22 int main(){
23     int n,k;
24     in(n); in(k);
25     for(int i=1; i<=n; ++i){
26         in(a[i]);
27     }
28     for(int i=1; i<=n; ++i){
29         if(front!=rear && idx[front]+k<=i) ++front;
30         while(front!=rear && que[rear-1]>=a[i]) --rear;
31         idx[rear]=i; que[rear]=a[i]; ++rear;
32         if(i>=k){
33             out(que[front]); putchar(' ');
34         }
35     }
36     putchar('\n');
37     front=rear=0;
38     for(int i=1; i<=n; ++i){
39         if(front!=rear && idx[front]+k<=i) ++front;
40         while(front!=rear && que[rear-1]<=a[i]) --rear;
41         idx[rear]=i; que[rear]=a[i]; ++rear;
42         if(i>=k){
43             out(que[front]); putchar(' ');
44         }
45     }
46     return 0;
47 } 

 

posted @ 2016-03-09 20:44  WABoss  阅读(179)  评论(0编辑  收藏  举报