HDU 5446 Unknown Treasure(中国剩余定理+卢卡斯定理)——2015 ACM/ICPC Asia Regional Changchun Online
Posted ITAK
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5446 Unknown Treasure(中国剩余定理+卢卡斯定理)——2015 ACM/ICPC Asia Regional Changchun Online相关的知识,希望对你有一定的参考价值。
On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician entered the cave because it is there. Somewhere deep in the cave, she found a treasure chest with a combination lock and some numbers on it. After quite a research, the mathematician found out that the correct combination to the lock would be obtained by calculating how many ways are there to pick m different apples amongInput On the first line there is an integer T(T≤20) representing the number of test cases.
Each test case starts with three integers n,m,k(1≤m≤n≤1018,1≤k≤10) on a line where k is the number of primes. Following on the next line are
Output For each test case output the correct combination on a line.
Sample Input
1 9 5 2 3 5
Sample Output
6
题目大意:
给定一个 n,m(1≤m≤n≤1018) ,求 C(n,m)%M 其中 M=p1∗p2∗...∗pk,其中pi为素数
解题思路:
设有
A=C(n,m),X=A(modM),Y=AM
,那么有
所以考虑中国剩余定理求得 X , 其中计算
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5+5;
void Exgcd(LL a, LL b, LL &x, LL &y)
if(b == 0)
x = 1;
y = 0;
return;
LL x1, y1;
Exgcd(b, a%b, x1, y1);
x = y1;
y = x1 - (a/b)*y1;
LL Pow(LL a, LL b, LL c)
LL ans = 1;
while(b)
if(b & 1) ans = (ans*a)%c;
b>>=1;
a = (a*a)%c;
return ans;
LL Multi(LL a, LL b, LL c)
LL ans = 0;
while(b)
if(b & 1) ans = (ans+a)%c;
b>>=1;
a = (a+a)%c;
return ans;
int C(int a, int b, int c)
if(b > a) return 0;
int tmp = min(b, a-b);
LL t1 = 1, t2 = 1;
for(int i=1; i<=tmp; i++)
t1 = t1*(a-i+1)%c;
t2 = t2*i%c;
LL x, y;
Exgcd(t2, c, x, y);
LL ans = t1*x%c;
ans = (ans%c+c)%c;
return ans;
LL Lucas(LL n, LL m, int p)
LL ans = 1;
while(n && m)
ans = ans*C(n%p, m%p, p) % p;
n /= p;
m /= p;
return ans;
LL p[15], a[15];
LL CRT(int n)
LL M = 1, ans = 0;
for(int i=0; i<n; i++) M *= p[i];
for(int i=0; i<n; i++)
LL _M = M/p[i];
LL x, y;
Exgcd(_M, p[i], x, y);
x = (x%p[i]+p[i])%p[i];
LL tmp = Multi(x, _M, M);
ans = (ans+Multi(tmp, a[i], M))%M;
ans = (ans%M+M)%M;
return ans;
int main()
int T; scanf("%d", &T);
while(T--)
LL n, m; scanf("%lld%lld",&n,&m);
int k; scanf("%d",&k);
for(int i=0; i<k; i++) scanf("%lld",&p[i]);
for(int i=0; i<k; i++) a[i] = Lucas(n, m, p[i]);
printf("%lld\\n",CRT(k));
return 0;
以上是关于HDU 5446 Unknown Treasure(中国剩余定理+卢卡斯定理)——2015 ACM/ICPC Asia Regional Changchun Online的主要内容,如果未能解决你的问题,请参考以下文章
hdu 5446 Unknown Treasure 卢卡斯+中国剩余定理
HDU 5446 Unknown Treasure(Lucas定理+CRT)
hdu 5446 Unknown Treasure (Lucas定理+中国剩余定理+快速乘)
HDU 5446 Unknown Treasure(中国剩余定理+卢卡斯定理)——2015 ACM/ICPC Asia Regional Changchun Online