O(N)的组合模版 HDU6114

来源:互联网 发布:傲剑九阴真经数据 编辑:程序博客网 时间:2024/06/08 11:45

通过预处理出全部数字的阶乘N[i],然后预处理出它们的逆元。

方法就是求出N!的逆元,然后从后向前推via[N-1]=via[N!]*v;

然后就可以求出组合了

hdu6114验证模版

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;const int L=1e5+7;typedef long long ll;const int maxn=L*2+800;const int mod=1e9+7;ll N[1005];ll niv[1005];ll pow1(ll a, ll b) {    ll ret = 1;    while(b) {        if(b & 1) ret = ret * a % mod;        a = (a * a) % mod;        b >>= 1;    }    return ret;}ll ni(ll x) {    return pow1(x,mod-2);}int C[1005][1005];int main(){    ll j,k,f1,f2,f3,f4,t1,t2,t3,t4;    ll n,m;    ll i;    ll M;M=1000;    N[0]=1ll;    for(i = 1; i <=M; i++)        N[i] = N[i-1] * i % mod;    niv[M]=ni(N[M]); //得到n的阶乘的逆元    for(i=M-1;i>=1;i--)        niv[i]=(niv[i+1]*(i+1))%mod; //预处理阶乘和逆可以秒出    for(i=1;i<=M;i++)        for(j=1;j<=i;j++) //C(i取j)        if(i!=j)        C[i][j]=((N[i]*niv[i-j])%mod)*niv[j]%mod;        else        C[i][i]=1;   ll r,c;   int T;   cin >> T;   while(T--){    cin >>r>> c;    if(c>r)swap(r,c);        cout << C[r][c] << endl;   }    return 0;}