zoukankan      html  css  js  c++  java
  • hdu 5446 Unknown Treasure 中国剩余定理+lucas

    题目链接

    求C(n, m)%p的值, n, m<=1e18, p = p1*p2*...pk. pi是质数。

    先求出C(n, m)%pi的值, 然后这就是一个同余的式子。 用中国剩余定理求解。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define ll long long
    ll a[17], b[17];
    void extend_Euclid(ll a, ll b, ll &x, ll &y)
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return;
        }
        extend_Euclid(b, a % b, x, y);
        ll tmp = x;
        x = y;
        y = tmp - (a / b) * y;
    }
    ll mul(ll a, ll n, ll mod)
    {
        a = (a%mod+mod)%mod;
        n = (n%mod+mod)%mod;
        ll ret = 0;
        while(n) {
            if(n&1)
                ret = (ret+a)%mod;
            a = (a+a)%mod;
            n >>= 1;
        }
        return ret;
    }
    ll CRT(ll a[],ll m[],int n)
    {
        ll M = 1;
        ll ans = 0;
        for(int i=1; i<=n; i++)
            M *= m[i];
        for(int i=1; i<=n; i++)
        {
            ll x, y;
            ll Mi = M / m[i];
            extend_Euclid(Mi, m[i], x, y);
            ans = (ans + mul(mul(Mi, x, M), a[i], M))%M;
        }
        return (ans+M)%M;
    }
    ll pow(ll a, ll b, ll mod)
    {
        ll ret = 1;
        while(b) {
            if(b&1) ret = ret*a%mod;
            a = a*a%mod;
            b /= 2;
        }
        return ret;
    }
    ll C(ll n, ll m, ll mod)
    {
        ll a = 1, b = 1;
        for(int i = 1; i <= m; i++) {
            b = b*i%mod;
            a = a*(n-i+1)%mod;
        }
        return a*pow(b, mod-2, mod)%mod;
    }
    ll lucas(ll n, ll m, ll mod)
    {
        if(m == 0)
            return 1;
        return lucas(n/mod, m/mod, mod)*C(n%mod, m%mod, mod)%mod;
    }
    int main()
    {
        ll t, n, m, k;
        cin>>t;
        while(t--) {
            cin>>n>>m>>k;
            for(int i = 1; i <= k; i++) {
                scanf("%lld", &a[i]);
            }
            for(int i = 1; i <= k; i++) {
                b[i] = lucas(n, m, a[i]);
            }
            ll ans = CRT(b, a, k);
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    HDU 1285
    HDU 1251
    HDU 1166
    UVA 10003
    HDU 5968
    CodeForces 371C
    POJ 2456
    POJ 2250
    oracle的start with connect by prior
    Hibernate session中的createCriteria方法
  • 原文地址:https://www.cnblogs.com/yohaha/p/5722439.html
Copyright © 2011-2022 走看看