poj-2823(单调队列)
题意:给你长度位n的数组,问每个长度为m的段的最值;
解题思路:这道题是单调队列的入门题;
#include<iostream> #include<algorithm> #include<queue> #include<cstdio> #define maxn 1000100 using namespace std; struct node { int val; int pos; }a[maxn]; int que[maxn]; int mn[maxn]; int mx[maxn]; int n,m; int s[maxn]; void get_min() { int head=1,tail=0,i; for(i=1;i<m;i++) { while(head<=tail&&a[tail].val>=s[i]) tail--; a[++tail].val=s[i]; a[tail].pos=i; } for(;i<=n;i++) { while(head<=tail&&a[tail].val>=s[i]) tail--; a[++tail].val=s[i]; a[tail].pos=i; while(a[head].pos<i-m+1) head++; mn[i-m+1]=a[head].val; } } void get_max() { int head=1,tail=0,i; for(i=1;i<m;i++) { while(head<=tail&&a[tail].val<=s[i]) tail--; a[++tail].val=s[i]; a[tail].pos=i; } for(;i<=n;i++) { while(head<=tail&&a[tail].val<=s[i]) tail--; a[++tail].val=s[i]; a[tail].pos=i; while(a[head].pos<i-m+1) head++; mx[i-m+1]=a[head].val; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&s[i]); get_max(); get_min(); for(int i=1;i<=n-m+1;i++) printf("%d ",mn[i]); printf("\n"); for(int i=1;i<=n-m+1;i++) printf("%d ",mx[i]); printf("\n"); return 0; }