码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 3048][Luogu P3069][USACO2013 Jan]Cow Lineup

时间:2018-01-12 11:32:57      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:time   []   usaco   https   new   img   splay   max   www   

[BZOJ 3048][Luogu P3069][USACO2013 Jan]Cow Lineup

 

<题意概括>

给定$n\left(n\leqslant100000\right)$个数,求删掉k种相同的数之后最长的相同数区间长度

 

<做法>

典型的双指针题目

由于数据范围较大,我们将数据离散化

使用两个指针

一个从区间的左端开始扫

另一个在Left指针的右端寻找最长的数字种数不超过k+1的区间并统计答案即可

 

<Code>

$Num[]$作离散化用

$num_{i}$储存原数组中第i个数离散化后的编号

$Cnt_{i}$为区间$[L,R]$中数字i出现的次数

cnt为区间$[L,R]$中数字种类数

技术分享图片
#include<cstdio>
#include<algorithm>
#define Fast register
#define Max(x,y) (x>y?x:y)
inline char Getchar(){
    static char BUF[16384],*S=BUF,*T=BUF;
    return(S==T)&&(T=(S=BUF)+fread(BUF,1,16384,stdin),S==T)?EOF:*S++;
}
inline int Getint(){
    Fast int s=0;Fast char c=Getchar();
    while(c<48||c>57)c=Getchar();
    while(c>47&&c<58)s=s*10+c-48,c=Getchar();
    return s;
}
int Cnt[100001];
int num[100001];
int Num[100001];
inline int Pos(const int*Array,const int&S,const int&T,const int&key){
    Fast int L=S,R=T,Mid;
    while(L<R){
        Mid=(L+R)>>1;
        key<=Array[Mid]?R=Mid:L=Mid+1;
    }
    return L;
}
int main(){
    Fast int N=Getint(),k=Getint();
    for(Fast int i=1;i<=N;++i)num[i]=Num[i]=Getint();
    std::sort(Num+1,Num+N+1);
    for(Fast int i=1;i<=N;++i)num[i]=Pos(Num,1,N,num[i]);
    Fast int L=1,R=1,cnt=0,Answer=0;
    while(L<=N){
        while(R<=N){
            cnt+=!Cnt[num[R]];
            if(cnt>k+1){--cnt;break;}
            ++Cnt[num[R++]];
        }
        Answer=Max(Answer,Cnt[num[L]]);
        cnt-=!--Cnt[num[L++]];
    }
    printf("%d",Answer);
    return 0;
}
[BZOJ 3048][Luogu P3069][USACO2013 Jan]Cow Lineup

[BZOJ 3048][Luogu P3069][USACO2013 Jan]Cow Lineup

标签:time   []   usaco   https   new   img   splay   max   www   

原文地址:https://www.cnblogs.com/Trisolaris/p/BZOJ-3048.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!