Description
有A~Z26个入口,现在有n位客人轮流从这些入口进入,同一时刻不会有超过一位客人进入,每个客人进固定的入口,一个入口在第一位客人来的时候打开,在最后一位客人进入之后关闭,一个入口如果是打开的就需要一个守卫,共有k个守卫,问是否存在某个时间段有某个入口开放但没有守卫
Input
第一行两个整数n,k分别表示客人数量和守卫数量,之后一个长度为n的只由大写字母组成的字符串表示第i位客人要进哪个入口(1<=n<=1e6,1<=k<=26)
Output
如果存在某个时间段有某个入口开放但没有守卫则输出YES,否则输出NO
Sample Input
5 1
AABBB
Sample Output
NO
Solution
记录每个字母出现的第一个位置L[i]和最后一个位置R[i],那么[L[i],R[i]]就表示第i个入口开放的时间段,对该区间加一,最后如果某个点的值超过k则YES,否则NO,区间加一可以用前缀和优化,时间复杂度O(n)
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
const int maxn=1000001;
int n,k,l[maxn],r[maxn],a[maxn];
char s[maxn];
int main()
{
while(~scanf("%d%d",&n,&k))
{
scanf("%s",s+1);
memset(l,0,sizeof(l));
for(int i=1;i<=n;i++)
{
int t=s[i]-'A';
if(!l[t])l[t]=i;
r[t]=i;
}
memset(a,0,sizeof(a));
for(int i=0;i<26;i++)
if(l[i])a[l[i]]++,a[r[i]+1]--;
int flag=0;
for(int i=1;i<=n;i++)
{
a[i]+=a[i-1];
if(a[i]>k)flag=1;
}
printf("%s\n",flag?"YES":"NO");
}
return 0;
}