zoj3903-數學公式(快速冪除法逆元組合數模板)

參考代碼:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<sstream>
#include<string>
#include<bitset>
using namespace std;

typedef long long LL;

const LL LINF = (1LL <<63);
const int INF = 1 << 31;


const int NS = 500010;
const int MS = 19;
const LL MOD = 1000000007;

LL qpow(LL x, LL y, LL mod)
{
    x %= mod;
    LL ans = 1;
    for(;y > 0; y>>= 1)
    {
        if(y & 1)
        {
            ans *= x;
            ans %= mod;
        }
        x *= x;
        x %= mod;
    }
    return ans;
}

//  (x / y)%mod
LL div(LL x, LL y, LL mod)
{
    x %= mod;
    LL ans = x * qpow(y, mod - 2, mod);
    ans %= mod;
    return ans;
}

LL combine(LL x, LL y, LL mod)
{
    if(x - y < y) y = x - y;
    x %= mod;
    if(x <= y) x += mod;

    LL ans = 1;
    LL t = 1;
    for(LL i = 0; i < y; i++)
    {
        ans *= (x - i);
        ans %= mod;

        t *= (i + 1);
        t %= mod;
    }
    ans = div(ans, t, mod);
    ans %= mod;
    return ans;
}

LL getmul(LL x, LL y, LL mod)
{
    x %= mod, y %= mod;
    LL ans = (x * y) % mod;
    return ans;
}

LL solve(LL n)
{
    LL T = combine(n + n + 3, 4, MOD);
    T %= MOD;

  //  n %= MOD;
    LL P = getmul(n + 1, n + 1, MOD);
    P *= (P - 1);
    P %= MOD;
    P = div(P , 12, MOD);

    LL C = getmul(n, n, MOD) * getmul(n, n + 1, MOD);
    C %= MOD;
    C = div(C, 2, MOD);

 //   printf("n = %I64d C = %I64d T = %I64d P = %I64d\n", n, C, T, P);
    LL ans = C + T - P;
    ans %= MOD;
    ans += MOD;
    ans %= MOD;

    return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("A.in", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif
    LL n;
    int nCase;
    scanf("%d", &nCase);
    for(int nT = 1; nT <= nCase; nT++)
    {
        cin >> n;

        LL ans = solve(n);
        cout<<ans<<endl;
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章