UVA

题意:已知歌单中的歌曲数目s,和部分的播放历史,问下一首可能播放的歌曲种数。

分析:

1、按照歌单数目s,将播放历史划分为几部分。

2、将播放历史的n首歌曲之前加上s首歌曲,之后加上s首歌曲,为防止标号重复,分别将其标号为100001 + i和200001 + i。

3、枚举这个新的序列中的每首歌,以s首为区间,区间开头为i,结尾为s + i - 1,若该区间里的数字不唯一,则不可能以该区间为标准划分,排除i%s这一划分可能。

4、判断区间里歌曲唯一的方法,记录每首歌出现次数,进入区间则加1,离开区间则减1,若区间长为s,里面每首歌都出现过1次,则此时sum一定为0,区间内是一种可行的播放顺序。

5、为排除之前s首和之后s首对歌曲唯一性判断的影响,只要初始化成之前的歌曲出现次数-1后不为1,之后的歌曲出现次数+1后不为2即可。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define lowbit(x) (x & (-x))
const double eps = 1e-8;
inline int dcmp(double a, double b){
    if(fabs(a - b) < eps) return 0;
    return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 300000 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int a[MAXN];
map<int, int> mp;
bool ans[MAXN];
int s, n;
int solve(){
    int sum = 0;
    for(int i = 1; i < n + s; ++i){
        int et = s + i - 1;
        if(--mp[a[i - 1]] == 1) --sum;
        if(++mp[a[et]] == 2) ++sum;
        if(sum != 0) ans[i % s] = false;
    }
    int cnt = 0;
    for(int i = 0; i < s; ++i){
        if(ans[i]){
            ++cnt;
        }
    }
    return cnt;
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        mp.clear();
        memset(a, 0, sizeof a);
        memset(ans, true, sizeof ans);
        scanf("%d%d", &s, &n);
        for(int i = 0; i < s; ++i){
            a[i] = 100001 + i;
            ++mp[a[i]];
        }
        for(int i = 0; i < n; ++i){
            scanf("%d", &a[i + s]);
        }
        for(int i = 0; i < s; ++i){
            a[s + n + i] = 200001 + i;
        }
        printf("%d
", solve());
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/7383491.html