6575: 11

题目描述

You are given an integer sequence of length n+1, a1,a2,…,an+1, which consists of the n integers 1,…,n. It is known that each of the n integers 1,…,n appears at least once in this sequence.
For each integer k=1,…,n+1, find the number of the different subsequences (not necessarily contiguous) of the given sequence with length k, modulo 109+7.
Notes
If the contents of two subsequences are the same, they are not separately counted even if they originate from different positions in the original sequence.
A subsequence of a sequence a with length k is a sequence obtained by selecting k of the elements of a and arranging them without changing their relative order. For example, the sequences 1,3,5 and 1,2,3 are subsequences of 1,2,3,4,5, while 3,1,2 and 1,10,100 are not.

Constraints
1≤n≤105
1≤ai≤n
Each of the integers 1,…,n appears in the sequence.
n and ai are integers.

输入

Input is given from Standard Input in the following format:
n
a1 a2 ... an+1

输出

Print n+1 lines. The k-th line should contain the number of the different subsequences of the given sequence with length k, modulo 109+7.

样例输入

3
1 2 1 3

样例输出

3
5
4
1

提示

There are three subsequences with length 1: 1 and 2 and 3.
There are five subsequences with length 2: 1,1 and 1,2 and 1,3 and 2,1 and 2,3.
There are four subsequences with length 3: 1,1,3 and 1,2,1 and 1,2,3 and 2,1,3.
There is one subsequence with length 4: 1,2,1,3.

在n+1个数中拿出k(1~n+1)个 数,不改变顺序,输出各自的种数C\binom{k}{n+1}求出所有可能的情况,然后去重

如果取出的数是重复数字中间的数时,不会发生重复,只有取之前之后的数字时才会重复,所以减去 C\binom{k-1}{m}

m是第一个重复数字前面 和 第二个重复数字后面的数字总和,然后用逆元计算组合数。

//Sinhaeng Hhjian
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<set>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 1e5+5;
ll jie[maxn], fa[maxn];
void init(){
    jie[0]=1;
    for(int i=1;i<maxn;i++){
        jie[i]=(jie[i-1]*i)%mod;
    }
}
ll qpow(ll a, ll b){
    ll ans=1;
    while(b){
        if(b%2)
            ans=(ans*a)%mod;
        a=(a*a)%mod;
        b/=2;
    }
    return ans;
}
ll C(ll n, ll m){
    if(n<m)
        return 0;
    return (jie[n]*qpow(jie[m]*jie[n-m]%mod, mod-2))%mod;
}
int main()
{
    init(); 
    int n;
    scanf("%d", &n);
    n++;
    ll temp, p1, p2;
    for(int i=1;i<=n;i++){
        scanf("%lld", &temp);
        if(fa[temp]==0)
            fa[temp]=i;
        else{
            p1 = fa[temp];
            p2 = i;
        }
    }
    ll dis = p2 - p1 - 1, m = n - dis - 2;
    for(int i=1;i<=n;i++){
        printf("%lld\n", (C(n, i) - C(m, i-1) + mod)%mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_30796379/article/details/81324854
11
今日推荐