您的位置:首页 > 其它

[bzoj3048] [Usaco2013 Jan]Cow Lineup

2016-06-18 15:30 337 查看
  一开始一脸懵逼。。

  后来才想到维护一左一右俩指针l和r..表示[l,r]这段内不同种类的数字<=k+1种。

  显然最左的、合法的l随着r的增加而不减。

  顺便离散化,记一下各个种类数字出现的次数就可以算出答案了。

  时间复杂度O(n)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+233;
struct zs{int v,id;}a[maxn];
int mp[maxn],sm[maxn];
int i,j,n,m,ans,num,K;

int ra;char rx;
inline int read(){
rx=getchar(),ra=0;
while((rx<'0'||rx>'9'))rx=getchar();
while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
}
bool cmp(zs a,zs b){return a.v<b.v;}
inline void add(int x){num+=!sm[x]++;}
inline void del(int x){num-=!--sm[x];}
int main(){
n=read(),K=read();
for(i=1;i<=n;i++)a[i].v=read(),a[i].id=i;
sort(a+1,a+1+n,cmp);int cnt=0;
for(i=1;i<=n;mp[a[i].id]=cnt,i++)
if(a[i].v!=a[i-1].v||i==1)cnt++;
int l=1,r=1;sm[mp[1]]++,num=ans=1;
for(r=2;r<=n;r++){
add(mp[r]);
while(num>K+1)del(mp[l]),l++;
ans=max(ans,sm[mp[r]]);
//      printf("%d--%d\n",l,r);
}
printf("%d\n",ans);
}


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