• POJ2823 Sliding Window 单调队列


    题目大意

    给出一段序列,一个长度一定的窗口从左到右滑动。求窗口滑动到每个位置时窗口内数字的最大值、最小值各是多少。n<=1e6。

    总体思路

    遇到这种对一个沿着一个方向滑动的区间求最值问题,可以运用单调队列优化。以求最小值为例。对整个序列构造一队列维护元素的下标,供多个窗口重复使用。设窗口左右端点各为l,r。要求对每个[l,r],通过一些操作,使得该队列满足下列条件:

    1. 元素只属于[l,r]。
    2. 从左到右下标对应的值必须是递增的。
    3. 元素∈[l,r]的数量最多。

    这样,该队列就会达到以下效果:

    1. 对于当前区间的最值,队首对应的值便是答案。
    2. 保证以后的[l+1, r+1]区间要找最值就在这个队列里找,不会漏

    这样每次遇到一个r,

    1. 不断从队首出队直到队首的下标>=l(满足条件1)
    2. 将对应数大于r对应数的队尾元素从队尾弹出(满足条件2),将r入列(满足条件3).
    3. 直接输出队首下标所对应数(利用条件2)
    #include <cstdio>
    #include <cstring>
    #include <deque>
    #include <cstdarg>
    
    using namespace std;
    
    #define LOOP(i, n) for(int i=0; i<n; i++)
    const int MAX_N = 1000010;
    
    struct IntDeque
    {
    	int a[MAX_N], head, tail;
    	void clear() { head = tail = 0; }
    	void push_back(int x) { a[tail++] = x; }
    	void pop_back() { tail--; }
    	void pop_front() { head++; }
    	bool empty() { return head == tail; }
    	int front() { return a[head]; }
    	int back() { return a[tail - 1]; }
    };
    
    
    void Proceed(int*val, int n, int k , bool(*opt)(int,int))
    {
    	static IntDeque pQ;
    	pQ.clear();
    	LOOP(curR, n)
    	{
    		int curL = curR - k + 1;
    		while (!pQ.empty() && pQ.front() < curL)
    			pQ.pop_front();
    		while (!pQ.empty() && opt(val[curR], val[pQ.back()]) )
    			pQ.pop_back();
    		pQ.push_back(curR);
    		if (curL >= 0)
    			printf("%d ", val[pQ.front()]);
    	}
    	printf("
    ");
    }
    
    bool _lt(int x, int y)
    {
    	return x < y;
    }
    bool _gt(int x, int y)
    {
    	return x > y;
    }
    
    int main()
    {
    #ifdef _DEBUG
    	freopen("c:\noi\source\input.txt", "r", stdin);
    #endif
    	int n, k;
    	static int val[MAX_N];
    	memset(val, 0, sizeof(val));
    	scanf("%d%d", &n, &k);
    	LOOP(i, n)
    		scanf("%d", i + val);
    	Proceed(val, n, k,_lt);
    	Proceed(val, n, k, _gt);
    	return 0;
    }
    

      

      

  • 相关阅读:
    CD4051
    sbit和sfr的定义
    EEPROM与FLASH的区别
    九LWIP学习笔记之最后的战役
    八LWIP学习笔记之用户编程接口(NETCONN)
    七LWIP学习笔记之传输控制协议(TCP)
    六LWIP学习笔记之用户数据报协议(UDP)
    java实现二叉查找树
    线程的锁对象
    MAP
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8484436.html
Copyright © 2020-2023  润新知