type
status
date
slug
summary
tags
category
icon
password
创建时间
Nov 13, 2024 02:03 AM
求组合数 , 。
时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32M,其他语言64M
解法一:递推法求组合数
由下面公式进行推导
解释:从 n 个数中选择 m 个数,可以分为
- 不选当前数:从 n - 1 个数中选择 m 个数;
- 选择当前数:从 n - 1 个数中选择 m - 1 个数。
这种递推的办法对空间消耗很大。当数据范围很大时,会超出内存限制,没办法求解。
解法二:通过逆元的方式求组合数
逆元的作用:
对于基本的四种运算而言,加减乘都符合"分配率",唯独除法不满足。 ,这种运算方式是错误的。如果要实现这种运算,就要把除法转化为乘法,假设 是 关于 的逆元。 可以转化为 。
而逆元的求法可以使用快速幂来求解。这里证明需要用到费马小定理(第二步)。
快速幂模板
因此,我们可以先求出所有的
feat
和 infeat
。feat[i] = feat[i-1] * i % mod
infeat[i] = infeat[i - 1] * i^-1 % mod = infeat[i - 1] * qmi(i, mod - 2, mod) % mod
解法三:卢卡斯定理
卢卡斯定理在本题不适用,但是也是一种求组合数的方法。他有限制,要求 的范围不能够太大,一般在 左右。其具体表示如下:
可知 和 —定是小于 的数, 可以直接求解。 继续使用 Lucas 定理求解
题目:给定三个整数 ,其中 是质数,请你输出 的值。