您的位置:首页 > 其它

[BZOJ3048][Usaco2013 Jan]Cow Lineup(单调队列)

2016-03-31 23:29 465 查看

题目描述

传送门

题解

首先离散化。

类似于单调队列的思想,一个头指针一个尾指针,向后移动的时候维护区间的种类数和它们的个数,保证区间种数-k=1。

边做边维护最大值。

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;

const int max_n=1e5+5;

int n,k,head,tail,kinds,Max;
int a[max_n],b[max_n],sum[max_n];
bool vis[max_n];

int main(){
//  freopen("lineup.in","r",stdin);
//  freopen("lineup.out","w",stdout);
scanf("%d%d",&n,&k);
for (int i=1;i<=n;++i){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
int cnt=unique(b+1,b+n+1)-b-1;
for (int i=1;i<=n;++i)
a[i]=lower_bound(b+1,b+n+1,a[i])-b;

head=1,tail=1;
sum[a[1]]=1,kinds=1,vis[a[1]]=true;
while (tail<n){
while (vis[ a[tail+1] ]||(!vis[ a[tail+1] ]&&kinds-1<k)){
tail++;
if (!vis[ a[tail] ]){
vis[ a[tail] ]=true;
kinds++;
sum[ a[tail] ]=1;
Max=max(Max,sum[ a[tail] ]);
}
else{
sum[ a[tail] ]++;
Max=max(Max,sum[ a[tail] ]);
}
if (tail==n) break;
}

if (sum[ a[head] ]==1){
kinds--;
vis[ a[head] ]=false;
}
sum[ a[head] ]--;
head++;
}

printf("%d\n",Max);
}


总结

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: