zoukankan      html  css  js  c++  java
  • 20201009 day30 复习2:滑动窗口

    LGP1886 滑动窗口/【模板】单调队列

    题意

    给定长(n)的序列(a),以及大小为(k)的窗口。现在窗口从左向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。(kle n le 10^6,a_iin[-2^{31},2^{31}))

    样例

    8 3
    1 3 -1 -3 5 3 6 7
    

    (第一行最小值,第二行最大值)

    -1 -3 -3 -3 3 3
    3 3 5 5 6 7
    

    题解

    以样例为例。用(q)表示单调队列,(p)表示其所对应的在原来列表里的序号。

    1. 原来队列中没有一个元素,直接令1进队。此时q={1},p={1}.
    2. 下面基于这样一个思想:如果把3放进去,如果后面两个数(k=3)都比他大,就有可能成为最小的。此时q={1,3},p={1,2}.
    3. 下面出现了-1,队尾元素3比-1大,意味着只要-1进队,那么3一定不可能成为最小值【原因是框3的同时一定会框住-1】,所以3从队尾弹出。进行同样的思考,1也从对尾出队。最终-1进队,此时q={-1},p={3}.
    4. 出现-3,同上面分析,-1出队,-3进队,q={-3},p={4}。
    5. 出现5,因为5>-3,根据第二条分析,5还是有希望的,所以5进队。此时q={-3,5},p={4,5}
    6. 出现3,3与队尾的5比较,3<5,按照第3条的分析,5从队尾出队,3再与-3比较,同第二条,3进队。此时q={-3,3},p={4,6}
    7. 出现6.6与3比较,因为3<6,所以不必出队。由于3以前元素都<3,所以不必再比较,6进队,因为-3此时已经在滑动窗口之外,所以-3从队首出队。此时q={3,6},p={6,7}
    8. 出现7.队尾元素6小于7,7进队。此时q={3,6,7},p={6,7,8}

    code

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    const int maxn=1000001;
    int n,k,a[maxn];
    int q[maxn],head,tail,p[maxn];
    int read(){
    	int ans=0,op=1;
    	char c;
    	c=getchar();
    	for(;(c<'0'||c>'9')&&c!='-';c=getchar());
    	if(c=='-') op=-1,c=getchar();
    	for(;(c>='0'&&c<='9');c=getchar()) ans*=10,ans+=c^48;
    	return ans*op;
    }
    void init(){
    	scanf("%d %d",&n,&k);
    	for(int i=1;i<=n;i++) a[i]=read();
    }
    void findmax(){
    	head=1,tail=0;
    	for(int i=1;i<=n;i++){
    		while(head<=tail&&q[tail]<=a[i]) tail--;
    		q[++tail]=a[i];
    		p[tail]=i;
    		while(p[head]<=i-k) head++;
    		if(i>=k) printf("%d ",q[head]);
    	}
    	printf("
    ");
    }
    void findmin(){
    	head=1,tail=0;
    	for(int i=1;i<=n;i++){
    		while(head<=tail&&q[tail]>=a[i]) tail--;
    		//只要队列里有元素,并且队尾元素比要处理的a[i]大,那么表示队尾元素已经不可能出场
    		//所以出队,知道队尾元素小于待处理的a[i],满足单调
    		q[++tail]=a[i];//处理值入队
    		p[tail]=i;//同时存下编号
    		while(p[head]<=i-k) head++;//如果队首元素已经不在窗口内,出队
    		if(i>=k) printf("%d ",q[head]);
    	}
    	printf("
    ");
    }
    int main(){
    	init();
    	findmin();
    	findmax();
    	return 0;
    }
    
    要做就做南波万
  • 相关阅读:
    HDU.6681.Rikka with Cake(欧拉公式 树状数组)
    Codeforces.449C.Willem, Chtholly and Seniorious(ODT)
    2017-2018 ACM-ICPC, Asia Daejeon Regional Contest (E,G,H,I,K)
    CF GYM.101987A.Circuits(线段树)
    2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)
    220
    219
    218
    217
    216
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/20201009day30-002.html
Copyright © 2011-2022 走看看