拓展卢卡斯定理模板完整注释
时间:2019-09-29
本文章向大家介绍拓展卢卡斯定理模板完整注释,主要包括拓展卢卡斯定理模板完整注释使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
#define _CRT_SECURE_NO_WARNINGS #include<bits/stdc++.h> using namespace std; //#define ll long long typedef long long ll; //拓展gcd,求解ax+by=gcd(a,b) void ex_gcd(ll a, ll b, ll & x, ll &y) { if (!b) { x = 1; y = 0; } else { ex_gcd(b, a%b, y, x); y -= x * (a / b); } } //求解a关于p的逆元,其中gcd(a,p)==1 ll inverse(ll a, ll p) { if (!a)return 0ll; ll x, y; ex_gcd(a, p, x, y); x = (x%p + p) % p; return x; } //快速幂a^b ll qpow(ll a, ll b, ll p) { ll res = 1; while (b) { if (b & 1)res = res * a%p; a = a * a%p; b >>= 1; } return res; } //中国剩余定理,求解x=a[i]%m[i]方程组 ll CRT(int n, ll *a, ll *m) { ll M = 1, res = 0; for (int i = 0; i < n; i++)M = M * m[i]; for (int i = 0; i < n; i++) { ll x, y; ll tm = M / m[i]; ex_gcd(tm, m[i], x, y); res = (res + tm * x*a[i] % M) % M; } return (res + M) % M; } //x表示质数,P表示分解的x^t //calc计算n!%P,P不一定质数,复杂度P*log(x)(n) ll calc(ll n, ll x, ll P) { if (!n)return 1; ll s = 1; //线性时间内计算1~P中不是x的倍数的乘积 //由于P不是质数,不能用威尔逊定理 //如果多组,这里可以提前打表优化,不过好像也不太方便,P总数太多 for (ll i = 2; i <= P; i++) { if (i%x)s = s * i%P; } s = qpow(s, n / P, P);//前面一部分的数关于P下面的循环 //这里是计算多余的,也就是n%P剩下的 for (ll i =2; i <=n%P; i++) if (i%x)s = s*i%P; return s * calc(n / x, x, P) % P; } //x表示质数,P表示分解的x^t //计算C(n,m)%P,P为一个质数的幂 ll multilucas(ll n, ll m, ll x, ll P) { ll cnt = 0; //下面分别用log的复杂度三个阶乘中含x的指数数目 //这一块不懂得话可以了解n!%p的相关性质 for (register ll i = n; i>0; i /= x) cnt += i / x; for ( ll i = m; i>0; i /= x)cnt -= i / x; for (ll i = n - m; i>0; i /= x)cnt -= i / x; return qpow(x, cnt, P) % P*calc(n, x, P) % P*inverse(calc(m, x, P), P) % P*inverse(calc(n - m, x, P), P) % P; } //求解C(n,m)%P的最终答案 ll ex_lucas(ll n, ll m, ll P) { ll cnt = 0; //a数组保存C(n,m)对每一种分解之后质因数求余的结果 //由于每一种质因数的t次方是互质的,所以用CRT即可求解 //p数组保存每一类质因数分解之后的答案 ll p[20], a[20];//最多质因数分解20个 for (ll i = 2; i*i <= P; i++) { //提前打素数表可以优化一点 if (P%i == 0) { p[cnt] = 1; while (P%i == 0) { p[cnt] = p[cnt] * i; P /= i; } a[cnt] = multilucas(n, m, i, p[cnt]); cnt++; } } //最后是一个质数 if (P > 1)p[cnt] = P, a[cnt++] = multilucas(n, m, P, P); return CRT(cnt, a, p); } int main() { ll n, m, p; scanf("%lld%lld%lld", &n, &m, &p); printf("%lld\n", ex_lucas(n, m, p)); cin >> n; return 0; }
原文地址:https://www.cnblogs.com/gzr2018/p/11607182.html
- 统计0到n之间1的个数[数学,动态规划dp](经典,详解)
- Selenium2+python自动化40-cookie相关操作
- 【干货】PyTorch实例:用ResNet进行交通标志分类
- 2017年浙江理工大学程序设计竞赛校赛 题解&源码(A.水, D. 简单贪心 ,E.数论,I 暴力)
- Selenium2+python自动化41-绕过验证码(add_cookie)
- C语言求最小公倍数和最大公约数三种算法(经典)
- Selenium2+python自动化47-判断弹出框存在(alert_is_present)
- Free Pascal初次体验(有亮点哦)
- HDU 1312 Red and Black(DFS,板子题,详解,零基础教你代码实现DFS)
- Selenium2+python自动化48-登录方法(参数化)
- 51Nod 1003 阶乘后面0的数量(数学,思维题)
- 如何查看某个用户指定时间段的ABAP开发记录
- Selenium2+python自动化49-判断文本(text_to_be_present_in_element)
- 洛谷 P1876 开灯(思维,枚举,规律题)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 线上问题分析之java dump文件生成
- python基础知识
- AtCoder Beginner Contest 177 A ~ E
- 2017 年ICPC 中国大陆区域赛铜牌题解
- 搜索(DFS BFS)专题练习
- AtCoder Beginner Contest 171
- AtCoder Beginner Contest 173 A ~ F(已经补完)
- AtCoder Beginner Contest 174 A ~ E
- AtCoder Beginner Contest 170
- 【队伍训练3】Codeforces Round #661 (Div. 3)
- 购物
- 指纹锁(自定义下比较重载下set的圆括号比较)
- 糖糖别胡说,我真的不是签到题目
- 分数线划定
- 小C的记事本