标签:数组 lis lse start ali until set limit UNC
You are listening to your music collection using the shu?e function to keep the music surprising. You assume that the shu?e 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 reshu?es 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 di?erent points in the future the next reshu?e might occur. A potential future reshu?e 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 speci?c song more than once.
On the ?rst line there exists one positive number: the number of test cases, at most 100. After that per test case there exists:
? One line with two integers s and n (1 ≤ s,n ≤ 100000): the number of di?erent songs in the playlist and the number of songs in the recorded playlist history.
? One line with n space separated integers, x1,x2,...,xn (1 ≤ xi ≤ s): the recorded playlist history.
1
6
0
7
题解:有了滑动窗口的思路之后这个题就变得很简单了,一个可行解就是所有窗口都满足每个数至多出现一次,统计可行解的时候只需看前s个,因为一旦确定了第一个窗口的末尾,所有窗口就都确定了,而第一个窗口的末尾只可能出现在前s个。统计一个窗口是否满足条件时,维护一个数组和一个计数器,数组中存的是数字出现次数,计数器记录的是当前窗口中只出现一次的数有几个。如果窗口长度等于计数器的大小,该窗口就是满足条件的。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 100000 + 100; 6 7 int n, s; 8 int seq[maxn], vis[maxn]; 9 bool can[maxn]; 10 11 int main() 12 { 13 //freopen("input.txt", "r", stdin); 14 int iCase; 15 scanf("%d", &iCase); 16 while (iCase--) { 17 scanf("%d%d", &s, &n); 18 for (int i = 0; i < n; i++) { 19 scanf("%d", &seq[i]); 20 } 21 memset(vis, 0, sizeof(vis)); 22 memset(can, true, sizeof(can)); 23 24 int tot = 0; 25 for (int i = 0; i < n + s; i++) { 26 if (i < n) { 27 if (++vis[seq[i]] == 1) tot++; 28 } 29 if (i >= s) { 30 if (--vis[seq[i - s]] == 0) tot--; 31 } 32 if (min(n - 1, i) - max(i - s + 1, 0) + 1 != tot) can[i%s] = false; 33 } 34 35 int ans = 0; 36 for (int i = 0; i < s; i++) { 37 if (can[i]) ans++; 38 } 39 printf("%d\n", ans); 40 } 41 return 0; 42 }
标签:数组 lis lse start ali until set limit UNC
原文地址:https://www.cnblogs.com/npugen/p/9676633.html