小a的学期 (组合数取模模板)

题目描述

小a是一个健忘的人,由于他经常忘记做作业,因此老师对他很恼火。
小a马上就要开学了,他学期一共2n

天,对于第i天,他有可能写了作业,也可能没写作业,不过他自己心里还有点B数,因此他会写恰好n天的作业
现在,小a需要安排他的学期计划,如果小a的学期中存在一天x,在这之前的x天中,他没写作业的天数 - 写作业的天数k

,那么老师就会把它开除,我们称这是一种不合法的方案
小a想知道他有多少种合法的方案

输入描述:

第一行三个整数n,k,pp表示对p取模

输出描述:

一个整数表示答案
示例1

输入

2 1 100007

输出

2

说明

总共有2n=4

合法的方案有
写了 没写 写了 没写
写了 写了 没写 没写
注意:没写 写了 没写 写了 是一种不合法的方案,因为在第一天时没写的天数-写了的天数1
 
示例2

输入

10 5 10000007

输出

169252

思路:在x位置之前出现m+k个不读书,m个读书则为不合法序列,将后面的不读书和读书互换,则该序列中含有n+k个不读书和n-k个读书

合法方案$C^{n}_{2n}$ 不合法方案$C^{n+k}_{2n}$ 答案相减即可

因为p不一定为质数,所以不能直接做。

$C^{m}_{n}=\dfrac {n!}{m!\left( n-m\right) !}$ 把上下所有质因子的指数求出来,在快速幂算即可。

#include <bits/stdc++.h>
#define ll long long
using namespace std;

template<typename T>
inline void read(T &x) {
    x = 0;T f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
    x *= f;
}

const int N = 2e6;
ll MOD, n, m;
bool vis[N + 10];
int prime[N], prin;

void getpri() {
    for (int i = 2; i <= N; i++) {
        if (!vis[i]) prime[++prin] = i;
        for (int j = 1; j <= prin && i * prime[j] <= N; j++) {
            vis[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

ll qp(ll a, ll b) {
    ll res = 1;
    while (b) {
        if (b & 1) res = res * a % MOD;
        a = a * a % MOD;
        b >>= 1;
    }
    return res;
}

// 计算x!中素因子p的指数 
ll cal(ll x, ll p) {
    ll res = 0;
    ll temp = p;
    while (x >= temp) {
        res += x / temp;
        temp *= p;
    }
    return res;
}

ll solve(ll n, ll m) {
    ll ans = 1;
    for (int i = 1; i <= prin && prime[i] <= n; i++) {
        ll cnt = cal(n, prime[i]) - cal(m, prime[i]) - cal(n - m, prime[i]);
        ans = (ans * qp(prime[i], cnt)) % MOD;
    }
    return ans;
}

int main() {
    getpri();
    read(n); read(m); read(MOD);
    printf("%lld\n", (solve(n * 2, n) - solve(n * 2, n + m) + MOD) % MOD);
    return 0;
}
View Code

 

posted @ 2019-07-11 20:23  Mrzdtz220  阅读(245)  评论(0)    收藏  举报