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
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\n" , ans ) ; return 0 ; }