题意
- 总共有s首歌,播完s首歌,打乱顺序,再继续播这s首。
- 给你n首歌的播放记录,请问下一首歌的情况有多少种。
题解
- 如果[i-s,i]能够成为一轮歌单,那么一定没有重复的歌。如果第i首歌和之前的重复了,那么[i-s,i]不会成为完整的歌单,同理[i+(k-1)*s,i+k*s]也不可能是一轮歌单。所以我们给i%s做上标记,它代表以i+k*s结尾的歌单。
代码
#include <bits/stdc++.h>
using namespace std;
int const N = 100000 + 10;
int s,n,a[N],ans[N],num[N],tot;
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(ans,true,sizeof(ans));
memset(num,0,sizeof(num));
tot = 0;
scanf("%d%d",&s,&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int tmp;
for(int i=1;i<=n+s;i++){
if(i <= n && ++num[a[i]]==1) ++tot;
if(i > s && --num[a[i-s]]==0) --tot;
if(i % s == 0) tmp = s;
else tmp = i % s;
if(min(i,n) - max(i-s,0) != tot) ans[tmp] = false; //这一句好好领悟
}
int res = 0;
for(int i=1;i<=s;i++)
if(ans[i]) res++;
printf("%d\n",res);
}
return 0;
}