You are listening to your music collection using the shuffle function
to keep the music surprising. You assume that the shuffle algorithm of
your music player makes a random permutation of the songs in the
playlist and plays the songs in that order until all songs have been
played. Then it reshuffles and starts playing the list again. You have
a history of the songs that have been played. However, your record of
the history of played songs is not complete, as you started recording
songs at a certain point in time and a number of songs might already
have been played. From this history, you want to know at how many
different points in the future the next reshuffle might occur. A
potential future reshuffle position is valid if it divides the
recorded history into intervals of length s (the number of songs in
the playlist) with the rst and last interval possibly containing less
than s songs and no interval contains a specic song more than once.
Input On the rst line one positive number: the number of testcases, at
most 100. After that per testcase: One line with two integers s and
n (1 s;n 100000): the number of different songs in the playlist
and the number of songs in the recorded playlist history. One line
with n space separated integers, x 1 ;x 2 ;:::;x n (1 x i s ): the
recorded playlist history. Output Per testcase: One line with the
number of future positions the next reshuffle can be at. If the
history could not be generated by the above mentioned algorithm,
output 0 .
通过滑动窗口O(n)预处理出每个长度为s的窗口是否符合要求,之后枚举起点即可。
方法二见这里
#include<cstdio>
#include<cstring>
#define M(a) memset(a,0,sizeof(a))
int a[500010],s,n,cnt[500010];
bool ok[500010];
int main()
{
int i,j,k,m,x,y,z,p,q,T,ans,tot;
bool b;
scanf("%d",&T);
while (T--)
{
M(a);
scanf("%d%d",&s,&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i+s]);
tot=0;
M(cnt);
M(ok);
for (i=2;i<=s+n;i++)
{
if (a[i-1])
{
cnt[a[i-1]]--;
if (cnt[a[i-1]]==1) tot--;
}
if (a[i+s-1])
{
cnt[a[i+s-1]]++;
if (cnt[a[i+s-1]]==2) tot++;
}
ok[i]=!tot;
}
ans=0;
for (i=2;i<=s+1;i++)
{
b=1;
for (j=i;j<=n+s;j+=s)
if (!ok[j])
{
b=0;
break;
}
if (b) ans++;
}
printf("%d\n",ans);
}
}