zoukankan      html  css  js  c++  java
  • 洛谷P1886 滑动窗口

    传送门啦

    以最大值为例,既然我们想要保证队列开头为答案,那么我们就要保证每次更新使最大值一直放在队列。那么如果存储的最大值该弹出了怎么办呢?我们只需要记录下每个元素的位置,判断是否在区间内即可。

    队头弹出后,第二位就变成了队头,我们就要保证这个数现在是区间内最大。那么是不是说,我们需要将这个长度为 $ k $ 的区间中的每一个数都存起来呢?不是的,并不是每个数被记录都有意义的。举个例子, $ a_i $ 和 $ a_j $ 两个数, $ i<j $ 。如果 $a_i >a_j $,那么两个数都应该记录;但是如果 $ a_i≤a_j $ ,那么当 $ a_j $ 进入区间后, $ a_i $ 的记录就没有意义了。很好理解,我们假设每个数作为区间最大值的次数为它的贡献,当 $ a_j $ 进入区间以后,在区间中存在的时间一定比 $ a_i $ 长,也就说明 $ a_i $ 一定不会再做贡献了,我们确定没有贡献的点,便可以直接删去,以维护单调队列的单调性。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <cmath>
    #define re register
    using namespace std ;
    const int maxn = 1e6 + 5 ;
    
    inline int read () {
    	int f = 1 , x = 0 ;
    	char ch = getchar () ;
    	while ( ch > '9' || ch < '0' ) {if(ch == '-') f = -1 ; ch = getchar () ; }
    	while ( ch >= '0' && ch <= '9' ) {x = (x << 1) + (x << 3) + ch - '0' ; ch = getchar () ; }
    	return x * f ;
    }
    
    int n , k , a[maxn] ;
    int head = 1 , tail ;
    
    struct Node {
    	int val , pos ;
    }q[maxn] ;
    
    int main () {
    	n = read () ; k = read () ;
    	for(re int i = 1 ; i <= n ; ++ i) {a[i] = read () ;}
    	for(re int i = 1 ; i <= n ; ++ i) {
    		while(head <= tail && q[head].pos + k <= i)  ++head ;
    		while(head <= tail && q[tail].val >= a[i]) --tail ;
    		q[++tail].val = a[i] ;
    		q[tail].pos = i ;
    		if(i >= k)  printf("%d " , q[head].val) ;
    	}
    	head = 1 , tail = 0 ;
    	printf("
    ") ;
    	for(re int i = 1 ; i <= n ; ++ i) {
    		while(head <= tail && q[head].pos + k <= i) ++head ;
    		while(head <= tail && q[tail].val <= a[i]) --tail ;
    		q[++tail].val = a[i] ;
    		q[tail].pos = i ;
    		if(i >= k) printf("%d " , q[head].val) ;
    	}
    	return 0 ;
    }
    
  • 相关阅读:
    boost::asio在VS2008下的编译错误
    Java集合框架——接口
    ACM POJ 3981 字符串替换(简单题)
    ACM HDU 1042 N!(高精度计算阶乘)
    OneTwoThree (Uva)
    ACM POJ 3979 分数加减法(水题)
    ACM HDU 4004 The Frog's Games(2011ACM大连赛区第四题)
    Hexadecimal View (2011ACM亚洲大连赛区现场赛D题)
    ACM HDU 4002 Find the maximum(2011年大连赛区网络赛第二题)
    ACM HDU 4001 To Miss Our Children Time (2011ACM大连赛区网络赛)
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/10414883.html
Copyright © 2011-2022 走看看