11 组合数

6575: 11

时间限制: 1 Sec  内存限制: 128 MB
提交: 88  解决: 26
[提交] [状态] [讨论版] [命题人:admin]

题目描述

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},然后再考虑去重的问题

发现取出的数是两个重复数字p之间的数时不会发生重复,只有取之前之后的数字时才会重复

所以减去一个 C\binom{k-1}{m},m是用 n+1-(d+1)-2    d是两个重复数字的距离,2是指这两个重复数字

然后用逆元计算组合数

代码:

#include <bits/stdc++.h>
using namespace std;
const  int maxx=1e5+100;
const int INF=1e9;
const int MOD=1e9+7;
typedef long long ll;
ll a[maxx];
ll mul[maxx];
int f[maxx];
ll n;
void init()
{
    mul[0]=1;
    for(int i=1; i<=n; i++){
        mul[i]= (mul[i-1]*i)%MOD;
    }
}
ll pow(ll a,ll b,ll MOD)
{
    ll ret=1;
    while(b){
        if(b&1)  ret=(ret*a)%MOD;
        a=a*a%MOD;
        b>>=1;
    }
    return ret%MOD;
}
ll C(ll a,ll b)
{
    if(b>a)  return 0;
    return (mul[a]*pow(mul[b]*mul[a-b]%MOD,MOD-2,MOD))%MOD;
}
int main()
{
    scanf("%lld",&n);
    n++;
    init();
    int p1,p2,d;
    for(int i=1; i<=n; i++){
        scanf("%lld",&a[i]);
        if(f[a[i]]==0)  f[a[i]]=i;
        else{
            p1=f[a[i]];
            p2=i;
        }
    }
    d=p2-p1-1;
    ll m=n-d-2;
    //cout<<d<<" "<<m<<endl;
    //cout<<n-1<<endl;
    for(ll i=1; i<=n; i++){
        printf( "%lld\n",(C(n,i)-C(m,i-1)+MOD)%MOD);
    }
    //cout<<"1"<<endl;
    return 0;
}

 

posted @ 2018-07-24 14:47  任小喵  阅读(195)  评论(0编辑  收藏  举报