快速幂、快速乘和组合数

快速幂($m^n$):

 1 ll quickpow(ll m, ll n, ll k)
 2 {
 3     ll res = 1;
 4     while (n > 0)
 5     {
 6         if (n & 1)
 7             res = (res * m) % k;
 8         m = (m * m) % k;
 9         n = n >> 1;
10     }
11     return res;
12 }

快速乘($mn$):

 1 ll quickmul(ll m, ll n, ll k)
 2 {
3 m = (m % k + k) % k; n = (n % k + k) % k;
4 ll res = 0; 5 while (n > 0) 6 { 7 if (n & 1) 8 res = (res + m) % k; 9 m = (m + m) % k; 10 n = n >> 1; 11 } 12 return res; 13 }

我觉得有必要换掉这个“龟速乘”

//不会爆long long

ll quickmul(ll a,ll b,ll mod) {
    ll ite = (1LL<<20)-1;
    return (a*(b>>20)%mod*(1ll<<20)%mod+a*(b&(ite))%mod)%mod;
}

全部组合($C_i^j \% P,1leq ileq maxn,0leq jleq i$)

int C[maxn][maxn];
void comp(int n, int P)
{
    memset(C, 0, sizeof(C));
    for (int i = 0; i <= n; i++)
    {
        C[i][0] = 1;
        for (int j = 1; j <= i; j++)  C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % P;
    }
}

部分组合($C_n^0,C_n^1,cdots,C_n^n$)

void comp(int n)
{
    C[0] = 1;
    for (int i = 1; i <= n; i++)  C[i] = C[i - 1] * (n - i + 1) / i;   //应该先乘后除,因为C[i-1]/i可能不是整数
}

单个组合($C_n^m$)

LL comp(LL n, LL m)
{
    double ans = 1;
    for (int i = 0; i < m; i++)  ans *= n - i;
    for (int i = 0; i < m; i++)  ans /= i + 1;
    return (LL)(ans + 0.5);
}

参考链接:http://www.cnblogs.com/qscqesze/p/5129856.html 

原文地址:https://www.cnblogs.com/lfri/p/9317093.html