acm数论之旅--组合数(转载)
ACM数论之旅8---组合数(组合大法好(,,• ₃ •,,) )
组合数并不陌生(´・ω・`)


我们都学过组合数
会求组合数吗
一般我们用杨辉三角性质
杨辉三角上的每一个数字都等于它的左上方和右上方的和(除了边界)

第n行,第m个就是,就是C(n, m) (从0开始)
电脑上我们就开一个数组保存,像这样


用递推求

1 #include<cstdio>
2 const int N = 2000 + 5;
3 const int MOD = (int)1e9 + 7;
4 int comb[N][N];//comb[n][m]就是C(n,m)
5 void init(){
6 for(int i = 0; i < N; i ++){
7 comb[i][0] = comb[i][i] = 1;
8 for(int j = 1; j < i; j ++){
9 comb[i][j] = comb[i-1][j] + comb[i-1][j-1];
10 comb[i][j] %= MOD;
11 }
12 }
13 }
14 int main(){
15 init();
16 }

https://ac.nowcoder.com/acm/contest/881#question E题,另外一种求组合数。
#include<bits/stdc++.h>
#define ll long long
#define M (ll)(1e9+7)
using namespace std;
ll CM[]={};
ll Pow(ll a,ll b){ //快速幂
a%=M;
ll ans = ;
for(;b;b>>=)
{
if(b&) ans = (ans*a)%M;
a = (a*a)%M;
}
return ans;
}
ll Quk(ll a,ll b){ //快速乘
a%=M;
ll ans = ;
for(;b;b>>=)
{
if(b&) ans = (ans+a)%M;
a = (a+a)%M;
}
return ans;
}
ll C(ll m,ll n){ //n>=m
return Quk(Quk(CM[n],Pow(CM[n-m],M-)),Pow(CM[m],M-))%M;
}
ll A(ll m,ll n){ //n>=m
return Quk(CM[n],Pow(CM[n-m],M-))%M;
}
int main()
{
ll a,b;
for(int i=;i<;i++) CM[i]=Quk(CM[i-],i);
while(cin>>a>>b)
{
ll ans=C(a+b,*(a+b));
if(a) ans-=C(a-,*(a+b));
if(b) ans-=C(b-,*(a+b));
cout<<(ans+*M)%M<<endl;
}
return ;
}
需要mod是质数
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3fffffff
#define maxn 100005
typedef long long ll;
ll n,m,k,t;
const ll mod = 1e9+;
ll fac[maxn];
ll inv[maxn];
ll qpow(ll a, ll b)
{
ll r = , t = a;
while (b) {
if (b & )r = (r*t) % mod;
b >>= ;t = (t*t) % mod;
}
return r;
}
void init()
{
fac[] = ;
for (int i = ;i <= mmax;i++) fac[i] = fac[i - ] * 1ll * i%mod;
inv[mmax] = qpow(fac[mmax], mod - );
for (int i = mmax - ;~i;i--) inv[i] = inv[i + ] * 1ll * (i + ) % mod;
}
ll C(ll n, ll m)
{
if (m>n) return ;
if (m == n || m == ) return ;
return fac[n] * 1ll * inv[n - m] % mod*inv[m] % mod;
}
int main(){
init();
while(~scanf("%lld%lld",&n,&m))
printf("%lld\n",(C(*m+*n,n+m)+mod-(C(*m+*n,n-)+C(*m+*n,m-))%mod)%mod);
}
(PS:大部分题目都要求求余,而且大部分都是对1e9+7这个数求余)
这种方法的复杂度是O(n^2),有没有O(n)的做法,当然有(´・ω・`)
因为大部分题都有求余,所以我们大可利用逆元的原理(没求余的题目,其实你也可以把MOD自己开的大一点,这样一样可以用逆元做)
根据这个公式

我们需要求阶乘和逆元阶乘
我们就用1e9+7来求余吧
long long F[];
void init(long long p)
{
F[] = ;
for(int i = ;i <= p;i++)
F[i] = F[i-]*i % ();
}
long long inv(long long a,long long m)
{
if(a == )return ;
return inv(m%a,m)*(m-m/a)%m;
}
long long Lucas(long long n,long long m,long long p)
{
long long ans = ;
while(n&&m)
{
long long a = n%p;
long long b = m%p;
if(a < b)return ;
ans = ans*F[a]%p*inv(F[b]*F[a-b]%p,p)%p;
n /= p;
m /= p;
}
return ans;
}
代码如下:

1 #include<cstdio>
2 const int N = 200000 + 5;
3 const int MOD = (int)1e9 + 7;
4 int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
5 void init(){
6 inv[1] = 1;
7 for(int i = 2; i < N; i ++){
8 inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
9 }
10 F[0] = Finv[0] = 1;
11 for(int i = 1; i < N; i ++){
12 F[i] = F[i-1] * 1ll * i % MOD;
13 Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
14 }
15 }
16 int comb(int n, int m){//comb(n, m)就是C(n, m)
17 if(m < 0 || m > n) return 0;
18 return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
19 }
20 int main(){
21 init();
22 }

acm数论之旅--组合数(转载)的更多相关文章
- acm数论之旅(转载) -- 逆元
ACM数论之旅6---数论倒数,又称逆元(我整个人都倒了( ̄﹏ ̄)) 数论倒数,又称逆元(因为我说习惯逆元了,下面我都说逆元) 数论中的倒数是有特别的意义滴 你以为a的倒数在数论中还是1/a吗 ( ...
- acm数论之旅(转载)--素数
https://www.cnblogs.com/linyujun/p/5198832.html 前言:好多学ACM的人都在问我数论的知识(其实我本人分不清数学和数论有什么区别,反正以后有关数学的知识我 ...
- acm数论之旅(转载)---最大公约数与最小公倍数
gcd(a, b),就是求a和b的最大公约数 lcm(a, b),就是求a和b的最小公倍数 然后有个公式 a*b = gcd * lcm ( gcd就是gcd(a, b), ( •̀∀•́ ) ...
- acm数论之旅(转载) -- 快速幂
0和1都不是素数,也不是合数. a的b次方怎么求 pow(a, b)是数学头文件math.h里面有的函数 可是它返回值是double类型,数据有精度误差 那就自己写for循环咯 LL pow(LL a ...
- acm数论之旅--中国剩余定理
ACM数论之旅9---中国剩余定理(CRT)(壮哉我大中华╰(*°▽°*)╯) 中国剩余定理,又名孙子定理o(*≧▽≦)ツ 能求解什么问题呢? 问题: 一堆物品 3个3个分剩2个 5个5个分剩3个 ...
- acm数论之旅--欧拉函数的证明
随笔 - 20 文章 - 0 评论 - 73 ACM数论之旅7---欧拉函数的证明及代码实现(我会证明都是骗人的╮( ̄▽ ̄)╭) https://blog.csdn.net/chen_ze_hua ...
- acm数论之旅--数论四大定理
ACM数论之旅5---数论四大定理(你怕不怕(☆゚∀゚)老实告诉我) (本篇无证明,想要证明的去找度娘)o(*≧▽≦)ツ ----------数论四大定理--------- 数论四大定理: 1.威 ...
- ACM数论之旅10---大组合数-卢卡斯定理(在下卢卡斯,你是我的Master吗?(。-`ω´-) )
记得前几章的组合数吧 我们学了O(n^2)的做法,加上逆元,我们又会了O(n)的做法 现在来了新问题,如果n和m很大呢, 比如求C(n, m) % p , n<=1e18,m<=1e18 ...
- ACM数论之旅17---反演定理 第一回 二项式反演(神说要有光 于是就有了光(´・ω・`))
终于讲到反演定理了,反演定理这种东西记一下公式就好了,反正我是证明不出来的~(-o ̄▽ ̄)-o 首先,著名的反演公式 我先简单的写一下o( ̄ヘ ̄*o) 比如下面这个公式 f(n) = g(1) + g ...
随机推荐
- 在SQL2005中修改数据库名称
SQL Server 2005中有个数据库HT_WisdomDataBaseCenter,现在要将其改名为HT_NBSBOneNetcs1步骤:(1) 分离数据库:打开management studi ...
- 十分钟理解JavaScript引擎的执行机制
关注专栏写文章 十分钟理解JavaScript引擎的执行机制 方伟景 千锋前端开发推动市场提升的学习研究者. 4 人赞同了该文章 首先,请牢记2点: JS是单线程语言 JS的Event Loop是JS ...
- 题解【洛谷P1618】 三连击(升级版)
设三个数分别为n1.n2.n3,因为三个数的比为A:B:C,取一份量i,使得A·i=x,B·i=y,C·i=z(·是*的意思). 所以我们的代码只需要枚举i,并以此判断n1.n2.n3是否为三位数且包 ...
- Python3标准库:string通用字符串操作
1. string:通用字符串操作 string模块在很早的Python版本中就有了.以前这个模块中提供的很多函数已经移植为str对象的方法,不过这个模块仍保留了很多有用的常量和类来处理str对象. ...
- 常见css属性
div { width: 100px; height: 100px; /* 表示行高 */ line-heigh ...
- html 未选择复选框不上传
问题 之前就遇到类似的问题,在一个列表中,如果有复选框,并且不选中 会导致这个复选框不上传,导致后台接收不到复选框数据 解决方法我想到的就是 <td> <input type=&qu ...
- git中全局设置用户名、邮箱
1.查看git配置信息:git config --list (可以查看所有的配置信息) 2.查看git用户名:git config user.name 3.查看邮箱配置:git config user ...
- 传奇HERO引擎给装备加套装属性技巧
装备加套装在复古的版本里比较少,但在1.76极品,轻变传奇,微变传奇和迷失版本里面用得比较多,每个引擎的方法相差不多,但也有一些小区别,今天给大家讲解下HERO引擎加套装的技巧. 第一步:我们打开M2 ...
- Vue-cli3 项目配置 Vue.config.js( 代替vue-cli2 build config)
Vue-cli3 搭建的项目 界面相对之前较为简洁 之前的build和config文件夹不见了,那么应该如何配置 如webpack等的配那 只需要在项目的根目录下新建 vue.config.js 文件 ...
- 【二叉搜索树】的详细实现(C++)
二叉搜索树的概念 从前面讨论折半搜索的性能中可知,如果每次从搜索序列的中间进行搜索,把区间缩小一半,通过有限次迭代,很快就能通近到所要寻找的元素.进一步,如果我们直接输入搜索序列,构造出类似于折半搜索 ...