HDU 5446 Unknown Treasure Lucas+CRT

来源:互联网 发布:2016淘宝客怎么推广 编辑:程序博客网 时间:2024/05/19 16:03

题意:给n,m,k和p1,p2….pk
求C(n,m)%p1* p2* …. pk
思路:比赛的时候并没有学…..
就是LUACS+CRT模板题

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define mem(a,b) memset(a,b,sizeof(a))#define lowbit(x) (x&(-x))typedef long long LL;#define maxn 10005const int inf=(1<<28)-1;LL quick_mod(LL a, LL b,LL p){    LL ans = 1;    a %= p;    while(b)    {        if(b & 1)        {            ans = ans * a % p;            b--;        }        b >>= 1;        a = a * a % p;    }    return ans;}LL C(LL n, LL m,LL p){    if(m > n) return 0;    LL ans = 1;    LL a=1,b=1;    for(int i=1; i<=m; i++)    {        a =a* (n + i - m)%p;        b =b* i%p;    }    ans=a*quick_mod(b,p-2,p)%p;    return ans;}LL Lucas(LL n, LL m,LL p){    if(m == 0) return 1;    return C(n % p, m % p,p) * Lucas(n / p, m / p,p) % p;}void exgcd(LL a, LL b, LL &d, LL &x, LL &y)//扩展欧几里德求逆元{    if (b == 0)        d = a, x = 1, y = 0;    else    {        exgcd(b, a%b, d, y, x);        y -= x * (a / b);    }}LL CRT(LL a[],LL m[],LL n)//中国剩余定理求解{    LL aa = a[1];    LL mm = m[1];    for (int i=1; i<=n; i++)    {        LL sub = (a[i] - aa);        LL d, x, y;        exgcd(mm, m[i], d, x, y);        if (sub % d) return -1;        LL new_m = m[i]/d;        new_m = (sub/d*x%new_m+new_m)%new_m;        aa = mm*new_m+aa;        mm = mm*m[i]/d;    }    aa = (aa+mm)%mm;    return aa;}LL r[maxn],m[maxn];int main(){    int T;    scanf("%d",&T);    while(T--)    {        LL M,n,k;        scanf("%lld%lld%lld",&M,&n,&k);        for(int i=1;i<=k;++i)        {            scanf("%lld",&m[i]);            r[i]=Lucas(M,n,m[i]);        }        printf("%lld\n",CRT(r,m,k));    }}
0 0