BZOJ1307: 玩具 单调队列

Description

小球球是个可爱的孩子,他喜欢玩具,另外小球球有个大大的柜子,里面放满了玩具,由于柜子太高了,每天小球球都会让妈妈从柜子上拿一些玩具放在地板上让小球球玩。 这天,小球球把所有的N辆玩具摆成一排放在地上,对于每辆玩具i,小球球都会给它涂上一个正整数value[i],以表示小球球对该玩具的喜爱程度,value[i]越小则表示他越喜爱。当然对于两辆不同的玩具u,v(u<>v),亦有可能value[i]=value[j],也就是说小球球对u,v两车的喜爱程度是一样的。 小球球很贪玩,他希望能从中间某个位置,连续的取出k辆玩具,使得这k辆车里喜爱程度最大的一辆车的喜爱程度正好等于k,且这k辆车中没有两辆车的喜爱程度是相同的。小球球希望知道k的最大值为多少。

Input

第一行一个整数N,表示小球球拥有的玩具数量。 接下来N行,每行一个整数,表示value[i]。

Output

一个整数k,即答案。

Sample Input

6
2
4
1
3
2
1

Sample Output

4

HINT

1<=Value[i]<=10^6
10%的测试数据 N<=10^5。
100%的测试数据 N<=10^6

Solution

拿个单调队列维护一下,维护单调递增,然后队头出队的条件就是有相同分数的车进来了

太久没写单调队列了$wa$了两三次...

$upd:$这题数据好像太水了。直接输出最大值也可以过,然后我这个单调队列好像有点锅...(我当时是怎么过去的)

#include <bits/stdc++.h>

using namespace std ;

const int N = 1e6 + 10 ;

int q[ N ], a[ N ] , vis[ N ] ;
int n ;

int main() {
    scanf( "%d" , &n ) ;
    int l = 0 , r = 1 , ql = 1 , ans = 0 ;
    for( int i = 1 ; i <= n ; i ++ ) {
        scanf( "%d" , &a[ i ] ) ;
        while( l < r && a[ q[ r ] ] <= a[ i ] ) r -- ;
        q[ r ++ ] = i ;
        if( !vis[ a[ i ] ] ) {
            vis[ a[ i ] ] ++ ;
        }else {
            while( a[ i ] != a[ ql ] && ql < i ) vis[ a[ ql ] ] -- , ql ++ ;
            ql ++ ;
            while( l < r && q[ l ] < ql ) l ++ ;
        }
        if( i - ql + 1 == a[ q[ l ] ] ) ans = max( ans , a[ q[ l ] ] ) ;
    }
    printf( "%d
" , ans ) ;
    return 0 ;
} 
原文地址:https://www.cnblogs.com/henry-1202/p/BZOJ1307.html