原题链接:https://vjudge.net/problem/UVA-12174
分类:滑动窗口
备注:思维,细节
注意n<s的情况
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int t,n,s,a[maxn*2],ok[maxn*2],cnt[maxn];
int main(void){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&t);
while(t--){
memset(ok,0,sizeof(ok));
memset(cnt,0,sizeof(cnt));
memset(a,0,sizeof(a));
scanf("%d %d",&s,&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
//把第一个数看作是第一组的第s,s-1,s-2,...,1个数
//ok[i]表示把第i个数看作当前窗口的第s个数是否符合条件
int tot=0;
for(int i=1,num=0;i<=s;i++){
if(i<=n)cnt[a[i]]++;
if(cnt[a[i]]>1)num++;
if(cnt[a[i]]==1)tot++;
if(num==0)ok[i]=1;
}
for(int i=s+1;i<=n;i++){
cnt[a[i]]++;
if(cnt[a[i]]==1)tot++;
cnt[a[i-s]]--;
if(cnt[a[i-s]]==0)tot--;
if(tot==s)ok[i]=1;
}
for(int i=max(n+1,s+1);i<=n+s-1;i++){
cnt[a[i-s]]--;
if(cnt[a[i-s]]==0)tot--;
if(tot==s-i+n)ok[i]=1;
}
int ans=0;
for(int i=1;i<=s;i++){
int flg=1;
for(int j=i;j<=n+s-1;j+=s)
if(!ok[j]){flg=0;break;}
if(flg)ans++;
}
printf("%d\n",ans);
}
return 0;
}