D - 11(逆元好题)

#include<bits/stdc++.h>
#define debug1(a) cout<<#a<<'='<< a << endl;
#define debug2(a,b) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<endl;
#define debug3(a,b,c) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<endl;
#define debug4(a,b,c,d) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<endl;
#define debug5(a,b,c,d,e) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<"  "<<#e<<" = "<<e<<endl;
#define debug0(x) cout << "debug0: " << x << endl
#define fr(t, i, n)for (long long i = t; i < n; i++)
#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define fi first
#define se second
#define int long long
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;

//#pragma GCC optimize(3,"Ofast","inline")
//#pragma GCC optimize(2)

/*

如果无视不同的要求,那么答案就是 C(n+1,k)。
什么时候会有重复的呢?
只可能是 a 中那两个相同的数字,恰好选了其中一个导致的。
设 a 中那两个相同数字的下标分别为 p 和 q(下标从 0 开始),
手玩一下可以发现,如果剩余的 k-1 个数是在 p 左边或 q 右边中选的,就会导致重复。
这一共有 m = p + (n-q) 个数。
因此答案为 C(n+1,k) - C(m,k-1)。

计算组合数需要逆元。

逆元组合数,无时无刻都要注意逆元的定义
*/

const int N = 100010,mod = 1e9 + 7;
int fact[N],ifact[N];
int a[N];
int to[N];
LL qmi(int a,int b,int p){                                          //快速幂
    LL res = 1;
    while(b){
        if(b&1)res = (LL)res * a % p;
        b = b >> 1;
        a = (LL)a * a % p;
    }
    return res;
}
LL C(int a,int b)
{
    return (LL)fact[a] * ifact[b] % mod * ifact[a - b] % mod;
}
void solve() 
{
    fact[0] = ifact[0] = 1;
    
    for(int i = 1;i < N;i++){
        fact[i] = (LL)fact[i - 1] * i % mod;                        //阶乘
        ifact[i] = (LL)ifact[i - 1] * qmi(i, mod - 2, mod) % mod;   //阶乘对于mod的乘法逆元
        //cout << fact[i] << " " << ifact[i] << endl;
    }

    int n;cin >> n;
    for(int i = 1;i <= n+1;i++)cin >> a[i];

    
    for(int i = 1;i <= n+1;i++)
    {
        if(!to[a[i]])to[a[i]] = i;
        else 
        {
            int l,r;
            l = to[a[i]],r=i;
            int m = l-1 + n - r + 1;
            
    
            //(LL)fact[a] * ifact[b] % mod * ifact[a - b] % mod
            for(int i = 1;i <= n+1;i ++)
            {
                if(m >= i-1)cout << (C(n+1,i) - C(m,i-1) + mod) % mod << endl;
                else cout << (C(n+1,i) % mod) << endl;
            }
            break;
        }
    }

}

signed main()
{
    /*
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    */

    int T = 1;//cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

posted @ 2023-04-06 15:35  俄罗斯刺沙蓬  阅读(16)  评论(0编辑  收藏  举报
返回顶端