求\(C_n^m \mod p\),写得太丑了qwq。

第一次写拓展Lucas竟然是在胡策的时候qwq写了两个半小时啊_(:з」∠)_还写挂了一个地方qwq

当然今天胡策我也是第一次写中国剩余定理(ˇˍˇ)

↑平时懒得动手的后果→_→

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll; int ipow2(int a, int b) {
int ret = 1, w = a;
while (b) {
if (b & 1) ret = ret * w;
w = w * w;
b >>= 1;
}
return ret;
} int ipow(int a, int b, int c) {
int ret = 1, w = a;
while (b) {
if (b & 1) ret = 1ll * ret * w % c;
w = 1ll * w * w % c;
b >>= 1;
}
return ret;
} int pic; const int N = 100003; struct data {int num, zhi;}; data work(int n, int p, int c) {
if (n == 1 || n == 0) return (data) {1, 0};
int ret1, las = n % pic, ret2 = 1; for (int i = 1; i <= las; ++i) {
if (i % p == 0) continue;
ret2 = 1ll * ret2 * i % pic;
} if (n >= pic) {
ret1 = ret2;
for (int i = las + 1; i < pic; ++i) {
if (i % p == 0) continue;
ret1 = 1ll * ret1 * i % pic;
}
ret1 = ipow(ret1, n / pic, pic);
} else
ret1 = 1; int tim = n / p;
data s = work(n / p, p, c);
return (data) {1ll * ret1 * ret2 % pic * s.num % pic, tim + s.zhi};
} void exgcd(int a, int b, ll &x, ll &y) {
if (b == 0) {x = 1; y = 0;}
else {
exgcd(b, a % b, x, y);
ll t = x;
x = y;
y = t - a / b * y;
}
} int inv(int a, int b) {
ll x, y;
exgcd(a, b, x, y);
return (x % b + b) % b;
} int Lucas(int n, int m, int p, int c) {
data s1, s2, s3;
pic = ipow2(p, c);
s1 = work(n, p, c);
s2 = work(m, p, c);
s3 = work(n - m, p, c); int tim = s1.zhi - s2.zhi - s3.zhi;
int num1 = s1.num, num2 = s2.num, num3 = s3.num;
num2 = inv(num2, pic); num3 = inv(num3, pic);
num1 = 1ll * num1 * num2 % pic * num3 % pic;
for (int i = 1; i <= tim; ++i)
num1 = 1ll * num1 * p % pic;
return num1;
} int prime[N], cnt = 0, cc[N], pc[N]; void Div(int p) {
int sq = ceil(sqrt(p));
for (int i = 2; i <= sq; ++i) {
if (p % i == 0) {
prime[++cnt] = i;
pc[cnt] = 1;
cc[cnt] = 0;
while (p % i == 0) {++cc[cnt]; p /= i; pc[cnt] *= i;}
}
}
if (p > 1) prime[++cnt] = p, cc[cnt] = 1, pc[cnt] = p;
} int n, m, k, p, x;
int num[N]; int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d%d%d", &n, &m, &k, &p); cnt = 0;
Div(p); for (int i = 1; i <= cnt; ++i)
num[i] = Lucas(n, m, prime[i], cc[i]); x = 0;
for (int i = 1; i <= cnt; ++i)
(x += (1ll * (p / pc[i]) * inv((p / pc[i]) % pc[i], pc[i]) % p * num[i] % p)) %= p;
printf("%d\n", x);
} return 0;
}

【拓展Lucas】模板的更多相关文章

  1. 拓展lucas结论及模板

    lucas及其拓展 模板题 洛谷 P4720 本文侧向结论和代码实现, 推导请转至lucas定理及其拓展的推导 https://blog.csdn.net/yuyilahanbao/article/d ...

  2. BZOJ 3129 [SDOI2013]方程 (拓展Lucas)

    题目大意:给定一个方程$X_{1}+X_{2}+X_{3}+X_{4}+...+X_{n}=M$,$\forall X_{i}<=A_{i} (i<=n1)$ $\forall X_{i} ...

  3. 数学:拓展Lucas定理

    拓展Lucas定理解决大组合数取模并且模数为任意数的情况 大概的思路是把模数用唯一分解定理拆开之后然后去做 然后要解决的一个子问题是求模质数的k次方 将分母部分转化成逆元再去做就好了 这里贴一份别人的 ...

  4. 【bzoj2142】【礼物】拓展Lucas定理+孙子定理

    (上不了p站我要死了,侵权度娘背锅) Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量 ...

  5. nefu 84 ( 拓展欧几里德模板题 )

    链接:传送门 思路:拓展欧几里德模板题,设大圣至少翻转 t 次,大圣起始位置为 x ,大圣目标位置为 y + n * s ( 大圣到达目标位置 y 可能需要多圈,所以用 s 来表示圈数 ),因为只能逆 ...

  6. 拓展Lucas小结

    拓展Lucas是解决大组合数取模非质数(尤其是含平方因子的合数)问题的有力工具... 首先对模数质因数分解,把每个质因子单独拎出来处理答案,然后用中国剩余定理(excrt)合并 问题转化为,对于每个质 ...

  7. BZOJ2142: 礼物(拓展lucas)

    Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店 ...

  8. BZOJ2982: combination Lucas模板

    2982: combination Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 734  Solved: 437[Submit][Status][Di ...

  9. 【BZOJ-2142】礼物 拓展Lucas定理

    2142: 礼物 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1313  Solved: 541[Submit][Status][Discuss] ...

随机推荐

  1. 【20151105noip膜你赛】bzoj3652 bzoj3653

    题目仿佛在讽刺我... 第一题: 题解: 考虑枚举区间右端点,维护所以左到当前的 and 和 or .注意 and 每次变化至少有一个二进制位从1变 0,or 每次至少有一个位从0变 1,所以最多有l ...

  2. 【51NOD】独木舟

    [算法]贪心 [题解]比较经典,用l,r两个定位指针分别从左右向中间推进. #include<cstdio> #include<algorithm> #include<c ...

  3. 【洛谷 P2783】 有机化学之神偶尔会做作弊 (双联通分量)

    题目链接 可能是除了<概率论>的最水的黑题了吧 用\(Tarjan\)缩点(点双联通分量),然后就是树上两点之间的距离了,跑\(LCA\)就好了. #include <cstdio& ...

  4. Port-knocking 简单教程

    0. "port knocking" 如字面意思,类似'敲门',只是这里敲的是'端口',而且需要按照顺序'敲'端口.如果敲击规则匹配,则可以让防火墙实时更改策略.从而达到开关防火墙 ...

  5. C/C++中手动获取调用堆栈【转】

    转自:http://blog.csdn.net/kevinlynx/article/details/39269507 版权声明:本文为博主原创文章,未经博主允许不得转载. 当我们的程序core掉之后, ...

  6. HighGUI图形图像界面初步——鼠标操作

    OpenCV中的鼠标操作和滑动条的消息映射方式很类似,都是通过一个中介函数配合一个回调函数来实现的,创建和指定滑动条回调函数为createTrackbar, 而指定鼠标操作消息回调函数的函数为setM ...

  7. python内建方法

    abs all any apply basestring bin bool buffer bytearray bytes callable chr classmethod cmp coerce com ...

  8. 流程控制--if条件

    /* if ....else .... */ [root@localhost test1]# vim .py //ADD #!/usr/bin/python >: print 'hello py ...

  9. vue-cli脚手架引入element UI的正确打开方式

    element UI官网教程:http://element-cn.eleme.io/#/zh-CN/component/quickstart 1.完整引入,直接了当,但是组件文件不是按需加载,造成多余 ...

  10. django “如何”系列7:错误汇报

    当你正在运行一个公共的站点的时候,你应该关掉DEBUG设置.这将使你的服务器运行的更快,同时也能预防别有用心的用户从你的错误页面看到你应用的一些详细配置信息.然而,当debug为false的时候,你将 ...