【转】AC神组合数取模大全
貌似少了几张图片,不过没有图片也没什么关系的感觉。
最后的究极篇也想出来了,但是貌似找不到题目,好尴尬。。
这个表示的是从n个元素中选取m个元素的方案数。
(PS.组合数求模似乎只用在信息学竞赛和 ACM竞赛等计算机编程设计大赛中……,求在现实中的运用)
可以知道当n,m 取得比较大的时候,组合数可能很大很大 (天文数字?无法度量?)
例如 C(100, 50) = 100891344545564193334812497256, 于是计算机的 64位整数型已经没法阻止它了!C(1000000000, 500000000) ? C( 2^50000, 2^49999 ) ? (Note:这里^表示次方,你能计算得到2的50000次级别的组合数么?它有多少位?)
看起来似乎高精度神马的都无法阻止这个邪恶的函数的急速扩张了……
庆幸的是,在竞赛中我们能够遇到的规模也就只有10^9级别(显然是mod上某个数字K,否则输出的文件那叫一个大啊……),这是多么的小呀呀呀呀!(Note: 相比较2^50000 -_-)
一. 入门篇:我会暴力!
(1) K = 1: 今天你学数论了么? 难度系数: 0
(2) (K> 1) n, m <= 1000 (n * n 是可以接受的) 难度系数: 1
递推!
c(n,m) =c(n - 1,m) + c(n – 1, m – 1)
某人: 555555 这个公式太复杂, 记忆不能!
c(5,2) = 10 = c(4,2) + c(4,1) = 6 + 4 ……
我们知道mod操作满足加法性质,即
(a + b) mod c = ( (a mod c) + (b mod c) ) mod c
c(n,m) = ( c(n - 1,m) + c(n – 1, m – 1) ) mod K
证明利用模的定义即可……很简单的
于是如此,我们只需要简单的开上一个 f[ N ][ N ],2个循环搞定!
其实我们遇到的大部分情况需要的 组合数 都可以用这个来搞定~
这里唯一可能被邪恶的其实是 K + K 溢出! 所以如果某个邪恶的题目出到 K = 2*10^9,在某些倒霉的场合会出现2个接近K的int相加,那么就溢出了!不要忘记用unsigned int… (我从来没出过这种题的!真的!)
(3) n 巨大(10^9 级别), m巨小(10^4级别), k 很小,大约10^9
a) m<= 1: 今天你学数论了么? 难度系数: 0
b) m<= 10000 难度系数: 2
可以发现分子分母的项数都少到可以接受!于是我们可以采取各种方式来通过:
i) 对于每个数字,分解素因子,合并,二分求幂! (你会数论!)
ii) 对于每个数字,只分解包含于K的素因子,例如K里面有一个素因子3,那么分解的时候我只考虑3呀,因为其他部分显然与3互质……最后统计3的次数即可……
例子:
计算C(10, 3) mod 36
C(10, 3) = (10 * 9 * 8) / (1 * 2 * 3)
对于分母:
1 : ok 逆元(有区别么?)
2: 没法逆元, (2, 36) = 2
3: 没法逆元, (3,36) = 3
为了神马啊!! 还不让人逆元啊!显然是因为邪恶的2和3,如果他们不存在,那么多么美好呀!
于是我开2个变量,记录2,3的次数
对于分子:
10: 里面只有1个2,去掉了2,剩下的部分是 10 / 2 = 5.
9: 里面只有2个3,去掉去掉, 剩下的是 9 / (3^2) = 1.
8: 里面只有3个2,去掉去掉,剩下的是 8 / (2^3) = 1
于是啊,分母我们把剩下的部分乘起来,得到了神马?得到了 和 2,3 因子完全无关的 部分mod 36的值!就是 5 * 1 * 1 = 5了。
接下来,还有分母呢
1: 逆元(其实你可以无视它)
2: 一个2,去掉去掉, 剩下1, 逆元继续是1(继续无视)
3: 一个3,同上
接下来发现,2有几个? 分子有4个,分母1个,所以一共只有4 – 1 = 3个
3有几个? 同上的做法,显然只有1个。
于是呢答案就是:
5 * 1 * 2^3 * 3^1 = 12( mod 36)
解释:
5 -> 分子除了因子2,3的积
1 ->分母除了因子2,3 的逆元的积
2^3 -> 最终统计发现有3个2
3^1 ->最终统计发现有1个3
请好好理解本例子,你会发现这个问题是如此的美妙!
经典例题:
http://acm.fzu.edu.cn/problem.php?pid=2020
c) m<= n 别想了!我不会!你会了教我!难度系数: -1
二. 基础篇:我会数论!
1) n,m<= 10^6, K是10^9级别
对于n! 分解素因子,这里就不说了,可以参考各种帖子。
之后保存个数,二分求幂啊啊啊啊啊
2) n,m<= 10^10, k是素数,并且K 很小(比如几百?)
其实遇到这种情况我都用一个叫Lucas定理的东西。
ni,mi 就是把 n,m分解p进制的第i位的值。
例如:
计算 C(12, 4) mod 7
n = 12 (15)(base_7)
m = 4 (4) (base_7)
为了对齐,我们前面的部分补0
m = 4 (04) (base_7)
于是
Ans = C(5,4) * C(1,0) mod 7= 5 (mod 7)
有人又要问了, 如果mi > ni 怎么办呀?
直接为0!!!!!!!!!
这里不给出证明,证明可以搜索到。同时由于这个应用的区域比较狭窄,显然有更简单,更好理解的算法,于是这里被无视了。
三. 究极篇
n,m <= 10^9, p <= 10^5
是不是怎么看怎么不可做呢?
第一次见到这种题目是不是觉得作者NC了,出个不可做题 >_<
第一次交发现一坨人全部WA,是不是觉得作者的数据搞疵?!!!!
首先要知道,这题其实等价是求:
求完直接合并一个模方程即可。(CRT)
p^c 的规模大约是10^5。
c 不是1,lucas阻止不了它。
n,m太大,因子分解也阻止不了它。
下面介绍我的做法:
假设 p = 3, c = 2,也就是mod 9
假设n = 19
n! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * …… * 19
要是可以快速得到 n! 中除掉3 以后 mod 9的结果,那么多好呀!
看3多讨厌,直接砍
type cal( int n) :
n! = [ 1 * 2 * 4 * 5 * 7 * 8 * … * 16 * 17 * 19 ] * (3 * 6 * 9 * 12 * 15 * 18)= [ 1 * 2 * 4 * 5 * 7 * 8 * … * 16 * 17* 19 ] * 3^6( 1 * 2 * 3 * 4 * 5 * 6)
然后发现后面的一坨实际上是 cal( n / p) !!!!
再看前半部分,尼玛是以 p^c 为周期的啊!!!
[1 * 2 * 4 * 5 * 7 * 8 ] = [10 * 11 * 13 * 14 * 16 *17 ] = (mod 9)
于是说白了,对于前面的部分,由于周期,都是浮云了
下面是 孤立出来的19
可以知道孤立出来的 长度 不超过 p^c ,于是暴力啊,暴力啊!
于是完美解决n! 中和 p无关的项 mod p^c的值!!!
接下来是分母部分,一模一样,无非多了一个求逆元(因为都和p没关系了,逆元必然存在)
我们来分析一下,这样的复杂度是如何的呢
每次递归,规模变为原来的 1/p
logp N的啊!!!
当然是层数= =
于是问题完美解决!
【转】AC神组合数取模大全的更多相关文章
- 组合数取模(lucas定理+CRT合并)(AC)
#include<bits/stdc++.h> #define re register #define int long long using namespace std; ; inlin ...
- 组合数取模Lucas定理及快速幂取模
组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1) , 此时较简单,在O(n2)可承受的情况下组合数的计算可以 ...
- 排列组合+组合数取模 HDU 5894
// 排列组合+组合数取模 HDU 5894 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 // 思路: // 定好m个人 相邻人之间k个座位 剩下就剩n-( ...
- hdu 3944 DP? 组合数取模(Lucas定理+预处理+帕斯卡公式优化)
DP? Problem Description Figure 1 shows the Yang Hui Triangle. We number the row from top to bottom 0 ...
- [BZOJ 3129] [Sdoi2013] 方程 【容斥+组合数取模+中国剩余定理】
题目链接:BZOJ - 3129 题目分析 使用隔板法的思想,如果没有任何限制条件,那么方案数就是 C(m - 1, n - 1). 如果有一个限制条件是 xi >= Ai ,那么我们就可以将 ...
- lucas定理解决大组合数取模
LL MyPow(LL a, LL b) { LL ret = ; while (b) { ) ret = ret * a % MOD; a = a * a % MOD; b >>= ; ...
- 2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理)
J. Ceizenpok’s formula time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- BZOJ_2142_礼物_扩展lucas+组合数取模+CRT
BZOJ_2142_礼物_扩展lucas+组合数取模 Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同 ...
- 组合数取模&&Lucas定理题集
题集链接: https://cn.vjudge.net/contest/231988 解题之前请先了解组合数取模和Lucas定理 A : FZU-2020 输出组合数C(n, m) mod p (1 ...
随机推荐
- hibernate,mybatis,beetlsql 全面比較
这是我的一个综合评分.总共分为12个单项.每一个单项最高5分.最低0分. 注意.评价仅仅包括这些软件提供的标准功能,不包括第三方提供的功能,如代码生成等. 开发效率 hibernate 能获取数据库 ...
- 利用PPPOE认证获取路由器中宽带账号密码
前言 回家时买了一台极路由准备换掉家里老掉牙的阿里路由器,想进后台看一下宽带账号密码,咦???后台密码是什么来着??? 我陷入了沉思,家里的路由器一般都是pppoe拨号,而路由器在与pppoe认证服务 ...
- 几个有关Hadoop自带的性能测试工具的应用
http://www.talkwithtrend.com/Question/177983-1247453 一些测试的描述如下内容最为详细,供你参考: 测试对于验证系统的正确性.分析系统的性能来说非常重 ...
- curl 执行post请求
#curl -l -H "Content-type: application/json;charset=UTF-8" -H "X-Forwarded-For: 20.20 ...
- java GC optimization, G1GC
引用 http://www.avricot.com/blog/?post/2010/05/03/Get-started-with-java-JVM-memory-(heap%2C-stack%2 ...
- ASP.NET MVC学习---(一)ORM框架,EF实体数据模型简介
现如今 对象关系映射(ORM)框架 被大量的使用于企业级应用的开发 为什么要使用ORM? ADO.NET操作数据库不好吗? 我们可以仔细想想 当我们使用ADO.NET操作数据库的时候 我们需要先获取连 ...
- Unity载入和内存管理机制
Unity几种动态载入Prefab方式的差异: 事实上存在3种载入prefab的方式: 一是静态引用,建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiat ...
- Cocos2d-x 3.2 大富翁游戏项目开发-第七部分 获取角色路径_2
在编写获取路径方法前,我们先把角色须要的动画文件载入进来,角色的文件为png 和 plist格式. player1_anim.png.plist player1_anim.pn ...
- perl学习笔记一
标量数据 标量:数字.字符.可以存储在标量变量中也可以从文件和设备中读取. 数字:所有数字内部格式相同——双精度浮点数. 浮点数直接量:程序员在程序中直接键入的数字. 整数直接量:6129804028 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程3.1 TwinCAT如何编写简单的计算器
把编写简单计算器作为入门的第一个范例程序,主要是因为比较简单,而且综合了HMI,数据类型,数据转换,PRG和FBD等功能块的混合等知识,个人认为还是比较适合用来快速上手的.由于是第一个范例,所以视频教 ...