题意:有个音乐播放器有乱序功能,能够随机播放1 ~ s首歌曲,每次随机播放完后再次打乱顺序随机播放(在播放完这一组的歌曲以前,不会再次乱序,直到所有播完)。现截取一段记录,给定播放的歌曲数 s 以及这段记录的长度 n ,而后输入这段记录,根据这段记录,求随机排序发生的时刻有几种可能。(1 <= s, n <= 100000)ios
对于符合要求的某一段来讲,每首歌最多出现一次,能够出现零次。spa
先预处理,求出对于每一个元素往前最多延伸至 s 长度时,可否符合要求,而后对每 s 的长度暴力求解便可。code
这里多处理告终束后的 s 长度,目的是最后多出来的,长度不足 s 的那一段也方便求解是否符合要求。blog
代码以下:排序
#include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<deque> #include<queue> #include<stack> #include<list> #define fin freopen("in.txt", "r", stdin) #define fout freopen("out.txt", "w", stdout) #define pr(x) cout << #x << " : " << x << " " #define prln(x) cout << #x << " : " << x << endl #define Min(a, b) a < b ? a : b #define Max(a, b) a < b ? b : a typedef long long ll; typedef unsigned long long llu; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const ll LL_INF = 0x3f3f3f3f3f3f3f3f; const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f; const double pi = acos(-1.0); const double EPS = 1e-6; const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1}; const ll MOD = 1e9 + 7; using namespace std; #define NDEBUG #include<cassert> const int MAXN = 100 + 10; const int MAXT = 200000 + 10; int T, s, n, a[MAXT], num[MAXT]; bool vis[MAXT]; set<int> st; bool solve(int lur){ for(int i = lur; i < n + s; i += s) if(!vis[i]) return false; return true; } int main(){ scanf("%d", &T); while(T--){ memset(vis, false, sizeof vis); memset(num, 0, sizeof num); memset(a, -1, sizeof a); st.clear(); scanf("%d%d", &s, &n); for(int i = 0; i < n; ++i) scanf("%d", a + i); int head = 0; for(int tail = 0; tail < n + s; ++tail){ if(a[tail] != -1 && ++num[a[tail]] > 1) st.insert(a[tail]); if(tail - head + 1 > s){ if(--num[a[head]] == 1) st.erase(a[head]); ++head; } if(st.empty()) vis[tail] = true; } int len = Min(n, s), ans = 0; for(int i = 0; i < len; ++i) if(solve(i)) ++ans; if(ans == len) ans = Max(ans, s); printf("%d\n", ans); } return 0; }