POJ 2823 Sliding Window
2011-06-22 14:45
211 查看
这是一道最最基础的使用双端队列优化的题目。题目的意思就是求出指定长度子序列的最大值和最小值。
如果说硬要弄一个方程的话,那就是f[i]=max/min(a[j]) (f[i]指以i结尾的子序列,a[j]指原序列中第k个元素。i-k+1<=j<=i)
显然我们可以通过单调队列来维护最大值和最小值,复杂度O(n)
按理说双端队列应该有两个域,一个存下标,一个存关键值,但是这道题中关键值很容易从原序列中取出,所以就省掉了这个域,在这里提醒一下刚接触单调队列的人。
当然,这个数据范围暴力RMQ也可以过,其实也不是很暴力啦,但是跟O(n)的算法比就不太优美了。
提示:在POJ上做这道题的时候,如果你超时了,或者几千ms水过,建议你在两个方面进行改进。
第一,不要使用STL。事实上,由于自身容器类型的限制,deque在时间空间上都是非常不适用于OI题目的。而自己写队列速度快,空间小,而且代码也短。
第二,参考一下我的代码中读入输出的部分(这个就是所谓蛋疼IO优化)。POJ上很多题目卡scanf和printf,在G++下光读入都可能会超时。遇到这种情况换C++编译好了。
如果说硬要弄一个方程的话,那就是f[i]=max/min(a[j]) (f[i]指以i结尾的子序列,a[j]指原序列中第k个元素。i-k+1<=j<=i)
显然我们可以通过单调队列来维护最大值和最小值,复杂度O(n)
按理说双端队列应该有两个域,一个存下标,一个存关键值,但是这道题中关键值很容易从原序列中取出,所以就省掉了这个域,在这里提醒一下刚接触单调队列的人。
当然,这个数据范围暴力RMQ也可以过,其实也不是很暴力啦,但是跟O(n)的算法比就不太优美了。
提示:在POJ上做这道题的时候,如果你超时了,或者几千ms水过,建议你在两个方面进行改进。
第一,不要使用STL。事实上,由于自身容器类型的限制,deque在时间空间上都是非常不适用于OI题目的。而自己写队列速度快,空间小,而且代码也短。
第二,参考一下我的代码中读入输出的部分(这个就是所谓蛋疼IO优化)。POJ上很多题目卡scanf和printf,在G++下光读入都可能会超时。遇到这种情况换C++编译好了。
//By YY_More #include<cstdio> char c; int i,n,k,f[1000050],L,R,H,x,D[1000050]; inline int getmin(){ while (D[L]<=i-k) L++; return f[D[L]]; }; inline void insertmin(){ while (L<=R&&f[D[R]]>=f[i]) R--; D[++R]=i; }; inline int getmax(){ while (D[L]<=i-k) L++; return f[D[L]]; }; inline void insertmax(){ while (L<=R&&f[D[R]]<=f[i]) R--; D[++R]=i; }; inline void put(int x){ if(x< 0){ putchar('-'); x = -x; } if(x == 0){ putchar('0'); return; } char s[20]; int bas = 0; for(;x;x/=10)s[bas++] = x%10+'0'; for(;bas--;)putchar(s[bas]); return; } int main(){ while (true){ c=getchar(); if (c==' ') break; n=n*10+c-48; } while (true){ c=getchar(); if (c=='\n') break; k=k*10+c-48; } int y=1; while (true){ c=getchar(); if (c=='\n') {f[++H]=x*y;break;} if (c==' ') {f[++H]=x*y;y=1;x=0;}; if (c=='-') y=-1; if (c>='0'&&c<='9') x=x*10+c-48; } L=0;R=-1; for (i=1;i<=n;i++){ insertmin(); if (i>=k) { put(getmin()); if (i<n) putchar(' '); } } putchar('\n'); L=0;R=-1; for (i=1;i<=n;i++){ insertmax(); if (i>=k) { put(getmax()); if (i<n) putchar(' '); } } putchar('\n'); return 0; }
相关文章推荐
- POj 2823 Sliding Window 单调队列
- 【POJ】2823 - Sliding Window 双段队列
- POJ 2823 Sliding Window
- poj 2823 Sliding Window
- POJ 2823 Sliding Window (单调队列)
- POJ 2823 Sliding Window(最小堆+最大堆)
- POJ 2823 Sliding Window
- POJ 2823 Sliding Window(单调队列||线段树)
- POJ-2823 Sliding Window
- poj 2823 Sliding Window
- POJ 2823 Sliding Window
- [单调队列] poj 2823 Sliding Window
- (poj 2823 Sliding Window)<单调队列裸题>
- poj 2823 Sliding Window
- 【单调队列】POJ 2823 Sliding Window
- POJ 2823 Sliding Window
- poj 2823 Sliding Window
- POJ 2823 Sliding Window [单调队列]【杂类】
- POJ 2823 Sliding Window(单调队列)
- poj 2823 Sliding Window (线段树,RMQ)