【jzoj3464】秀姿势

题目描述

“蓝猫淘气三千问,看蓝猫,我有姿势我自豪!”话说能考上HYSBZ的孩纸们肯定都是很有姿势的孩纸们,但是大家普遍偏科,都只有一门科目考得好。已知HYSBZ的入学考试科目数量小于等于10^9,而有n个学生参加了入学考试。

现在HYSBZ要刷人了,招生办每一次刷人会把一个科目考得好的人全部刷掉,但是最多不能刷超过K次。(刷就是不录取)而HYSBZ的校长看录取名单时,最喜欢看的就是连续都是同一个科目考得好的人。

他定义完美学生序列为连续且考得好的科目都为同一门的学生序列。现在招生办主任想让你帮他设计一种录取方案,使得最长的完美学生连续子序列尽量长。

输入

共 N+1 行,第一行 2 个正整数 n,K,n 表示入学考试人数,K 表示刷人次数上限。

接下来 N 行,每行仅一个正整数 A i ,为 i 号学生所考得好的科目。


输出

仅 1 个正整数,为最长的最长完美学生序列。


样例输入

 

9 1
2
7
3
7
7
3
7
5
7

 

样例输出

4

 



题解

队列。任意时刻,只需保证队列里只有 k+1 种科目,然后用队列里科目的众数去更新答案。

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long

const int maxn=100000+50;

int n,k,a[maxn],cnt[maxn],tot,maxx;
int ls[maxn],ans,l;

template<typename T>void read(T& aa){
    char cc; ll ff;aa=0;cc=getchar();ff=1;
    while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
    if(cc=='-') ff=-1,cc=getchar();
    while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    aa*=ff;
}

int main(){
//    freopen("sugata.in","r",stdin);
//    freopen("sugata.out","w",stdout);
    read(n),read(k);
    for(int i=1;i<=n;i++) read(a[i]),ls[++ls[0]]=a[i];
    sort(ls+1,ls+1+ls[0]);
    int sz=unique(ls+1,ls+ls[0]+1)-ls;
    for(int i=1;i<=n;i++) a[i]=lower_bound(ls+1,ls+sz+1,a[i])-ls;
    for(int r=1;r<=n;r++){
        ++cnt[a[r]];
        if(cnt[a[r]]==1) tot++;
        while(tot>k+1){
            --cnt[a[l]];
            if(cnt[a[l]]==0) tot--;
            l++;
        }
        ans=max(ans,cnt[a[r]]);
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2018-10-19 19:11  rld  阅读(163)  评论(0编辑  收藏  举报