中石油 6575 (乘法逆元+费马小定理)

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

题意:给你n+1个数 1-n每个数起码出现一次,也就是说最多只有一个重复的数,问你组成[1---n+1]长度的序列有多少种方案,其实就是给你1到n的数,另外再加一个1到n的数。

思路    假设没有重复的点,C(n+1,k)k取1~n+1,设i,j重复(j>i) 可以推出 有重复的C(n-(j-i),k-1),所以数量为C(n+1,k)-C(n-(j-i),k-1);

组合数C(n,m)=n!/(m!*(n-m)!),而这里需要mod 所以想到乘法逆元inv[i]=(i^mod-2)%mod;1/m!=(m^mod-2)%mod;然后用快速幂求。。。

#include<stdio.h>
#include<queue>
#include<math.h>
#include<time.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#define LL long long
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(a) a&(-a)
#define PI acos(-1)
#define shortime(a)  std::ios::sync_with_stdio(a);
using  namespace std;
const LL mod=1e9+7;
//long long cmp(node a,node b){ if(a.x==b.x) return a.r>b.r;return a.x>b.x;}
int maxn (int a,int b,int c){return max(max(a,b),max(b,c));}
LL min(LL a,LL b) {return a<b?a:b;}
int gcd (int a,int b){return b==0?a:gcd(b,a%b);}
LL  quick(LL x,LL n){ LL ans=1,temp=x; while(n){if(n%2==1){ ans=(ans*temp)%mod;} n/=2;temp=temp*temp%mod;}return ans;}
LL inv[100005]={1,1},f1[100005]={1,1},f2[100005]={1,1};
void init()
{
    for(int i=2;i<=100005;i++)
    {
        f1[i]=(f1[i-1]*i)%mod;
        inv[i]=quick(i,mod-2);
        f2[i]=(f2[i-1]*inv[i])%mod;
        //printf("%d %lld %lld %lld \n",i,f1[i],inv[i],f2[i]);
    }
}
LL C(LL n,LL m)
{
    
    return f1[n]*f2[n-m]%mod*f2[m]%mod;
}
int n,vis[100005];
int main()
{
    init();

    scanf("%d",&n);
    mem(vis,0);
    LL temp;
    for(int i=1;i<=n+1;i++)
    {
        int x;
        scanf("%d",&x);
        if(vis[x])
        {
            temp=n-(i-vis[x]);
        }
        vis[x]=i;
    }
    LL sum;
   // printf()
    for(int i=1;i<=n+1;i++)
    {
          sum=C((LL) (n+1),(LL) (i))%mod;
           //printf("%lld\n",sum);
          if(temp>=i-1)
          {
              sum=(sum-C((LL)temp,(LL)(i-1))+mod)%mod;
          }
          printf("%lld\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41485193/article/details/81326529
今日推荐