題意:有個音樂播放器有亂序功能,能夠隨機播放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; }