【单调队列】扫描

链接

https://www.luogu.org/problemnew/show/P2032

大意

给定一个长度为 n 的序列 a ,求出所有 S i 满足 S i = m a x ( a k )           k = i . . i + m           i = 1.. m

思路

单调队列
于求前 m 个数的最小值类似:
https://blog.csdn.net/xuxiayang/article/details/80737937
维护稍有不同

代码

#include<deque>
#include<cstdio>
using namespace std;
deque<int>q;
int n,m,f,a[2000001];char c;
int read()
{
    f=0;
    while(c=getchar(),c<=47||c>=58);f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;
    return f;
}
void write(int x){if(x>9)write(x/10);putchar(x%10+48);return;}
int main()
{
    n=read();m=read();a[1]=read();
    q.push_back(1);//第一个的最大值显然是自己
    for(int i=2;i<=n;i++)
    {
        a[i]=read();
        while(q.size()&&a[i]>a[q.back()]) q.pop_back();//这里是求最大值,把小于它的全部踢掉
        q.push_back(i);//放入
        if(i-q.front()==m) q.pop_front();//因为是求m个,所以当超过m个时也要踢掉
        if(i>=m) write(a[q.front()]),putchar(10);//输出
    }
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/80739083