题目描述
一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。
题目解析
没啥意思。
单调队列练手题
题解里看到特别好的一句话:
每次新元素进来时:
1.把比新元素“老”,价值还不如新元素的一律出队。
2.无论价值多高,过期的元素一律出队。
Code
#include<iostream> #include<cstdio> #include<queue> using namespace std; const int MAXN = 2000000 + 5; struct Node { int id; int val; friend bool operator >= (Node x,Node y) { return x.val >= y.val; } } a[MAXN]; int n,m; int ans[MAXN]; deque<Node> Q; inline int rd() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) {f=ch=='-'?-1:1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++) { a[i].id = i; a[i].val = rd(); } ans[1] = 0; for(int i = 2;i <= n;i++) { while(!Q.empty() && Q.back() >= a[i-1]) Q.pop_back(); Q.push_back(a[i-1]); while(Q.front().id < i-m) Q.pop_front(); ans[i] = Q.front().val; } for(int i = 1;i <= n;i++) printf("%d ",ans[i]); return 0; }