"The main effect of the topic"
You're listening to the music player, which takes the form of random playback. The principle of random playback first randomly produces a 1~n arrangement, and then in this order to play the song. After playing all the songs in this sequence, randomly generate a 1~n arrangement, and then continue playing.
Now give you a playback history, this history is not complete, think it is the beginning of the record, some songs have been played but not recorded.
Now give you a history of playing music from a moment, and how many songs there are in the player.
The first song in the history may be the number of a random list, how many possibilities are there altogether?
Ideas
First preprocessing, with a bool array OK record, OK "I" means that the first position at the beginning of the number of consecutive S is not the same.
And then the first one to enumerate the song is x, first check before the S-x song is not the same, this can be preprocessed to judge.
Then starting from X, Judge x,x+s,x+2*s ... is not all satisfied with the conditions can be.
Code
/* * UVa 12174-shuffle */#include <iostream> #include <cstdio> #include <cstring>
using namespace Std;
typedef long long Int64;
const int INF = 0X3F3F3F3F;
const int MAXN = 100010;
int s, n;
int ARR[MAXN];
int CNT[MAXN];
BOOL FIRST[MAXN], OK[MAXN];
preprocessing inline void init () {memset (0, sizeof (a));
memset (OK, 0, sizeof (OK));
memset (CNT, 0, sizeof (CNT));
First[0] = true;
int i;
For (i=0 i<s && i<n &&!cnt[arr[i]; ++i) {first[i+1] = true;
Cnt[arr[i]] = 1;
} if (i==n && i<s && First[i]) {while (i++<s) first[i] = true;
memset (CNT, 0, sizeof (CNT));
Ok[n] = true;
int count=0;
for (int i=n-1; i>=0;-i) {if (cnt[arr[i]]++ = 0) {++count; } if (count = = S | | N-I<S&AMp;&n-i==count) {Ok[i] = true;
} if (I+s-1<n) {if (--cnt[arr[i+s-1]] = = 0) {--count;
BOOL Check (int st) {while (St < n) {if (!ok[st]) is return false;
St = = s;
return true;
int main () {int ncase;
scanf ("%d", &ncase);
while (ncase--) {scanf ("%d%d", &s, &n);
for (int i=0; i<n; ++i) scanf ("%d", &arr[i]);
Init ();
int ans = 0;
for (int i=0; i<s; ++i) if (First[i] && check (i)) ++ans;
printf ("%d\n", ans);
return 0; }
See more highlights of this column: http://www.bianceng.cn/Programming/sjjg/