公式

$$C_n^m\%p=C_{n/p}^{m/p}*C_{n\%p}^{m\%p}\%p~~(p为素数)$$

代码如下

typedef long long ll;
ll mod_pow(ll x, ll n, ll mod)
{
ll res = 1;
while (n > 0)
{
if (n & 1)
res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
ll comb(ll n, ll m, ll p)
{
if (m > n)
return 0;
ll a = 1, b = 1;
m = min(n - m, m);
while(m)
{
a = (a * n--) % p;
b = (b * m--) % p;
}
return a * mod_pow(b, p - 2, p) % p;
}
ll Lucas(ll n, ll m, ll p)
{
if (m == 0)
return 1;
return comb(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}

例题

HDU 3037

解析:m个相同的豆子,放到n个不同的树里,有多少种方法。有$C_{n+m}^m$种。具体详解请看下面的扩展中的插板法。

代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll mod_pow(ll x, ll n, ll mod)
{
ll res = 1;
while (n > 0)
{
if (n & 1)
res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
}
ll comb(ll n, ll m, ll p)
{
if (m > n)
return 0;
ll a = 1, b = 1;
m = min(n - m, m);
while(m)
{
a = (a * n--) % p;
b = (b * m--) % p;
}
return a * mod_pow(b, p - 2, p) % p;
}
ll Lucas(ll n, ll m, ll p)
{
if (m == 0)
return 1;
return comb(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
int main(int argc, char* argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);
ll T, n, m, p;
cin >> T;
while (T--)
{
cin >> n >> m >> p;
cout << Lucas(n + m, m, p) << endl;
}
return 0;
}

扩展

插板法

适用类型

一组相同的元素,分成若干不同的组,每组至少一个元素。

例题1

将8个相同的小球放到3个不同的盒子,每个盒子至少放一个球,一共有多少种方法。

解:8个盒子,有7个空,分到3个盒子,需要插2块板,$C_7^2=21$种。

对于不满足每组至少一个元素条件的,应该先转化为标准形式。

例题2

将8个相同的小球放到3个不同的盒子,每个盒子至少放两个球,一共有多少种方法。

解析:先往每一个盒子里放一个小球。转化为:5个相同的小球放到不同的盒子,每个盒子至少放1个小球,一共有多少种方法。$C_4^2=6$种。

例题3

将8个相同的小球放到3个不同的盒子,有多少种方法。

解析:我们先让每个盒子吐出1个球,使得每个盒子至少一个球,分球的时候再让盒子吃回去。转化为:11个相同的球放到3个不同的盒子中,每个盒子至少一个,有多少种方法。$C_{10}^2=45$种。

例题4

$a+b+c=10$有多少组正整数解。

解析:转化为:10个相同的小球,放到不同的3个盒子中,每个盒子至少一个,有多少方法。$C_9^2=36$种。

例题5

$a+b+c=10$有多少组非负整数解。

解析:转化为:13个相同的小球,放到不同的3个盒子中,有多少方法。$C_{12}^2=66$种。

例题6

$a+b+c\leqslant 10$有多少组非负整数解。

解析1:转化为$a+b+c+d =10$,即10个相同的球,放到4个不同的盒子中,有多少方法。$C_{13}^3=286$种。

解析2:列举所有情况:$a+b+c=0(C_2^2)$,$a+b+c=1(C_3^2)$,$\cdots$,$a+b+c=10(C_{12}^2)$,$\sum\limits_{i=2}^{12}C_i^2=C_{13}^3=286$种。

注:$\sum\limits_{i=m}^nC_i^m=C_{n+1}^{m+1}$。

杨辉三角性质之一:斜线上数字的和等于其向左(从左上方到右下方的斜线)或向右拐弯(从右上方到左下方的斜线),拐角上的数字。

随机推荐

  1. Windows IIS 安装配置PHP环境

    一. 概述 二.安装PHP 1.到php官网下载最新版PHP http://windows.php.net/download 三.配置IIS PHP环境

  2. 闲扯json取值,联想map取值。

    将list转json(list中的Bean的属性名称为变量,若为常量没必要采用此方式,直接转实体类即可) JSONArray json = JSONArray.fromObject(list); fo ...

  3. OC基础 NSDate

    OC基础  NSDate #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @auto ...

  4. iOS 10 的一些变化

    原文链接:http://www.jianshu.com/p/9756992a35ca

  5. Web项目中出现乱码

    (不知道怎么写才好) 分两种情况: 1.如果是 get 方式 单独修改: new String(str.getBytes("原来的编码"), "想要的编码") ...

  6. mybatis逆向工程失败

    [ERROR] Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.6:generate ( ...

  7. AngularJS集合数据遍历显示

    AngularJS集合数据遍历显示 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  8. 每日踩坑 2018-01-09 WebAPI会如何面对 枚举 参数?

    这一块确实有些疑问, 众所周知 枚举参数我们传送枚举值所对应的数字就行了, 以前 Leader 跟我讲过,枚举参数会将字符串值也能够成功转化,而且枚举值定义之外的数字也可以被转为枚举值. 主要的问题在 ...

  9. Jupyter notebook 文件路径

    Jupyter notebook 文件路径 1. 默认工作路径:C:\Users\think 2. 修改工作路径: C:\Users\think\.jupyter路径下,无配置文件 打开命令提示符:( ...

  10. jQuery 1.9/2.0/2.1及其以上 on 无效的解决办法

    jQuery 1.9/2.0/2.1及其以上版本无法使用live函数了,然而jQuery 1.9及其以上版本提供了on函数来代替.本文讲解了jQuery on函数的使用方法,以及在使用jQuery函数 ...