POJ 2823 Sliding Window <速度特快 单调队列>
2016-09-02 12:59
453 查看
题目:
求连续的k个中最大最小值,k是滑动的,每次滑动一个
用双端队列维护可能的答案值
如果要求最小值,则维护一个单调递增的序列
对一开始的前k个,新加入的如果比队尾的小,则弹出队尾的,直到新加入的比队尾大,加入队尾
从第k+1个到最后一个,按照上述规则,压入新数,然后弹出队首元素(满足队首元素对应原来序列的位置必须在视窗内,否则,继续弹出下一个)
2068ms g++
786ms g++
求连续的k个中最大最小值,k是滑动的,每次滑动一个
用双端队列维护可能的答案值
如果要求最小值,则维护一个单调递增的序列
对一开始的前k个,新加入的如果比队尾的小,则弹出队尾的,直到新加入的比队尾大,加入队尾
从第k+1个到最后一个,按照上述规则,压入新数,然后弹出队首元素(满足队首元素对应原来序列的位置必须在视窗内,否则,继续弹出下一个)
2068ms g++
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; #define maxn 1000003 int a[maxn], q[maxn]; int n, m; inline int read(){ int res(0),sign(1); char c; while(1){ c = getchar(); if('0' <= c && c <= '9') { res = c - '0'; break; } else if(c == '-') { sign = -1; break; } } while(1){ c = getchar(); if('0' <= c && c <= '9') res = res*10 + c - '0'; else break; } return res * sign; } 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; } void getmin() { int i; int head = 0, tail = -1; for(i = 0; i < m-1; i++) { while(head <= tail && a[q[tail]] > a[i]) tail--; q[++tail] = i; } for(i = m-1; i < n; i++) { while(head <= tail && i - q[head] >= m) head++; while(head <= tail && a[q[tail]] > a[i]) tail--; q[++tail] = i; if(i != n - 1) put(a[q[head]]),putchar(' '); } put(a[q[head]]),putchar('\n'); } void getmax() { int i; int head = 0, tail = -1; for(i = 0; i < m-1; i++) { while(head <= tail && a[q[tail]] < a[i]) tail--; q[++tail] = i; } for(i = m-1; i < n; i++) { while(head <= tail && i - q[head] >= m) head++; while(head <= tail && a[q[tail]] < a[i]) tail--; q[++tail] = i; if(i != n - 1) put(a[q[head]]),putchar(' '); } put(a[q[head]]); } int main() { int i; n=read(),m=read(); for(i = 0; i < n; i++) scanf("%d", &a[i]); getmin(); getmax(); return 0; }
786ms g++
#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; }
相关文章推荐
- Sliding Window POJ - 2823 单调队列
- Sliding Window(单调队列讲解与例题)
- POJ 2823 Sliding Window/单调队列
- Sliding Window POJ - 2823 单调队列
- Sliding Window POJ - 2823 单调队列
- Sliding Window poj 单调队列的简单应用
- Sliding Window POJ - 2823 单调队列
- <斜率优化><单调队列>——2.T_OY(踢欧阳^_^)
- (poj 2823 Sliding Window)<单调队列裸题>
- Sliding Window POJ - 2823 单调队列
- <单调队列>3.烽火传递
- POJ 2823:Sliding Window 单调队列
- 单调队列优化多重背包(含构造问题<POJ 1742 coin>)
- [POJ 2823] Sliding Window · 单调队列
- <单调队列><二分>4.偷懒的西西
- POJ 2823:Sliding Window 单调队列
- HDU 3530 Subsequence(区间最值差>=m且<=k的最大长度、双单调队列)
- POJ2823:Sliding Window(单调队列||线段树)
- POJ 2823 Sliding Window 单调队列
- POJ 3162 Walking Race 树的直径+单调队列(其实暴力也可以>_<)