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)个 数,不改变顺序,输出各自的种数
因为最多只有两个数字会重复,所以先,然后再考虑去重的问题
发现取出的数是两个重复数字p之间的数时不会发生重复,只有取之前之后的数字时才会重复
所以减去一个 ,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;
}