博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucas+中国剩余定理 HDOJ 5446 Unknown Treasure
阅读量:6542 次
发布时间:2019-06-24

本文共 2216 字,大约阅读时间需要 7 分钟。

 

题意:很裸,就是求C (n, m) % (p1 * p2 * p3 * .... * pk)

分析:首先n,m<= 1e18, 要用到Lucas定理求,当然p[]的乘积<=1e18不能直接计算,但是pi<=1e5。接下来要知道中国剩余定理,所以先对每个pi计算出bi,注意在中国剩余定理的两数相乘会爆long long,所以用乘法取模,"但是这样的话exgcd返回值如果是负数就会出错,所以乘之前要取模成正的",这句话不是很懂。

收获:老祖宗的智慧结晶一定要学

 

代码:

/************************************************* Author        :Running_Time* Created Time  :2015/9/15 星期二 13:40:41* File Name     :J.cpp ************************************************/#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1typedef long long ll;const int N = 1e5 + 10;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;ll f[N]; void init(int p) { f[0] = 1; for (int i=1; i<=p; ++i) f[i] = f[i-1] * i % p;} ll pow_mod(ll a, ll x, ll p) { ll ret = 1; while (x) { if (x & 1) ret = ret * a % p; a = a * a % p; x >>= 1; } return ret;} ll Lucas(ll n, ll k, ll p) { //C (n, k) % p ll ret = 1; while (n && k) { ll nn = n % p, kk = k % p; if (nn < kk) return 0; ret = ret * f[nn] * pow_mod (f[kk] * f[nn-kk] % p, p - 2, p) % p; n /= p, k /= p; } return ret;}ll multi_mod(ll a, ll b, ll p) { //a * b % p a = (a % p + p) % p; b = (b % p + p) % p; ll ret = 0; while (b) { if (b & 1) { ret += a; if (ret >= p) ret -= p; } b >>= 1; a <<= 1; if (a >= p) a -= p; } return ret;}ll ex_GCD(ll a, ll b, ll &x, ll &y) { if (b == 0) { x = 1; y = 0; return a; } ll d = ex_GCD (b, a % b, y, x); y -= x * (a / b); return d;}ll China(int k, ll *b, ll *m) { ll M = 1, x, y, ret = 0; for (int i=1; i<=k; ++i) M *= m[i]; for (int i=1; i<=k; ++i) { ll w = M / m[i]; ex_GCD (w, m[i], x, y); ret += multi_mod (multi_mod (x, w, M), b[i], M); } return (ret + M) % M;}int main(void) { int T; scanf ("%d", &T); while (T--) { ll p[11], b[11]; ll n, m; int k; scanf ("%I64d%I64d%d", &n, &m, &k); for (int i=1; i<=k; ++i) { scanf ("%I64d", &p[i]); init (p[i]); b[i] = Lucas (n, m, p[i]); } printf ("%I64d\n", China (k, b, p)); } return 0;}

  

转载于:https://www.cnblogs.com/Running-Time/p/4810476.html

你可能感兴趣的文章
SQL查询,排除指定字段
查看>>
大学记忆(1)[记忆之殇]
查看>>
2)杨辉三角[2]递归实现
查看>>
pdf怎么拆分成多个pdf
查看>>
php中使用mail()函数发送邮件
查看>>
如何安装和使用零售密钥激活Windows 8.1 专业版
查看>>
初探kali linux笔记
查看>>
MySQL存储引擎中的MyISAM和InnoDB区别详解
查看>>
shell常用正则表达式
查看>>
postfix邮件配置
查看>>
oracle专用服务器模式和共享服务器模式详解
查看>>
javascript实现网页中图片的自动切换代码
查看>>
WebService 笔记
查看>>
刘宇凡:浅谈流氓式用户体验
查看>>
UITabBarController使用详解
查看>>
self parent $this关键字分析--PHP
查看>>
使用SSM的时候添加自定义的监听器(实现已知的那几个接口)出现报错的问题
查看>>
我的友情链接
查看>>
LVS负载均衡LAMP平台
查看>>
wex5怎么配合做seo 优化
查看>>