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

来源:互联网 发布:len在vb中什么意思 编辑:程序博客网 时间:2024/06/05 14:51

题目描述

传送门

题解

首先离散化。
类似于单调队列的思想,一个头指针一个尾指针,向后移动的时候维护区间的种类数和它们的个数,保证区间种数-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);}

总结

0 0