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 ...
随机推荐
- 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解
一.前言 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...
- linux 关键字搜索文件
在www目录下查找包含关键字’summer’,且后缀名为php文件的操作命令 find /www/ -name '*.php' |xargs grep '/Summer'
- ASP.NET MVC 获取表单数据
public class Person { public string Name{get;set;} public string Phone{get;set;} } view层 @model Mode ...
- 2020牛客竞赛 DP F 碎碎念
作者:儒生雄才1链接:https://ac.nowcoder.com/discuss/366644来源:牛客网 题目连接:https://ac.nowcoder.com/acm/contest/300 ...
- Python中super的用法【转载】
Python中super的用法[转载] 转载dxk_093812 最后发布于2019-02-17 20:12:18 阅读数 1143 收藏 展开 转载自 Python面向对象中super用法与MRO ...
- jQuery操作css
jQuery addClass() 方法 向被选中元素添加class属性,参数为属性值 $("div").addClass("imp"); 也可以同时向多个元素 ...
- Python之旅的开始day1
Python有哪些种类: JPython.IronPython.JavaScriptPython.RubyPython.CPython(即将开始学习种类,最为常见的种类).pypy pypy:这是用C ...
- FLV格式解析(转)
flv格式详解+实例剖析:https://www.cnblogs.com/lidabo/p/9018548.html FLV 封装格式解析:https://www.cnblogs.com/leisur ...
- 零Web知识个性化Blog
需要使用到的工具 Chrome Pycharm 自定主题的CSS 申请博客的Js权限 设置博客选项 打开Chrome修改查看CSS样式,Windows(F12),MacOS(Command+Optio ...
- Python_装饰器函数
楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班了.写了一个函数,就交给其他开发用了. def func1(): print('in func1') 季度末,公司的领导要给大家发绩 ...