zoukankan      html  css  js  c++  java
  • hdu 5446 Unknown Treasure lucas和CRT

    Unknown Treasure

    Time Limit: 1 Sec  

    Memory Limit: 256 MB

    题目连接

    http://acm.hdu.edu.cn/showproblem.php?pid=5446

    Description

    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 among n of them and modulo it with M. M is the product of several different primes.

    Input

    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 k different primes p1,...,pk. It is guaranteed that M=p1⋅p2⋅⋅⋅pk≤1018 and pi≤105 for every i∈{1,...,k}.

    Output

    For each test case output the correct combination on a line.

    Sample Input

    1
    9 5 2
    3 5

    Sample Output

    6

    HINT

    题意

    给你n,m,num

    然后给你num个数,k1,k2....,knum

    然后让你求C(n,m)%(k1*k2*....*knum)

    题解:

    首先,C(n,m)%k我们是会求的,大概这部分子问题是一个很经典的题目。

    假设你会求了,那么我们就可以由此得到num个答案,是%k1,k2,k3....knum后得到的值

    然后我们就可以看出就是类似韩信点兵一样的题,三个人一组剩了2个,五个人一组剩了2个这种……

    这时候,就用中国剩余定理处理处理就好了

    注意ll*ll会爆,所以得手写个快速乘法

    代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //**************************************************************************************
    
    void extend_gcd(ll a,ll &x,ll b,ll &y)
    {
        if(b==0)
        {
            x=1,y=0;
            return;
        }
        ll x1,y1;
        extend_gcd(b,x1,a%b,y1);
        x=y1;
        y=x1-(a/b)*y1;
    }
    ll inv(ll a,ll m)
    {
        ll t1,t2;
        extend_gcd(a,t1,m,t2);
        return (t1%m+m)%m;
    }
    ll qpow(ll x,ll y,ll m)
    {
        if(!y)return 1;
        ll ans = qpow(x,y>>1,m);
        ans = ans*ans%m;
        if(y&1)ans = ans*x%m;
        return ans;
    }
    
    ll nump(ll x,ll p)
    {
        ll ans = 0;
        while(x)ans+=x/p,x/=p;
        return ans;
    }
    ll fac(ll n,ll p,ll pk)
    {
        if(n==0)return 1;
        ll ans = 1;
        for(ll i=1;i<=pk;i++)
        {
            if(i%p==0)continue;
            ans = ans*i%pk;
        }
        ans = qpow(ans,n/pk,pk);
        ll to = n%pk;
        for(ll i =1;i<=to;i++)
        {
            if(i%p==0)continue;
            ans = ans*i%pk;
        }
        return fac(n/p,p,pk)*ans%pk;
    }
    ll cal(ll n,ll m,ll p ,ll pi,ll pk)
    {
        ll a = fac(n,pi,pk),b=fac(m,pi,pk),c=fac(n-m,pi,pk);
        ll d = nump(n,pi)-nump(m,pi)-nump(n-m,pi);
        ll ans = a%pk * inv(b,pk)%pk * inv(c,pk)%pk*qpow(pi,d,pk)%pk;
        return ans*(p/pk)%p*inv(p/pk,pk)%p;
    }
    ll mCnmodp(ll n,ll m,ll p)
    {
        ll ans = 0;
        ll x = p;
        for(ll i =2;i*i<=x&&x>1;i++)
        {
            ll k=0,pk=1;
            while(x%i==0)
            {
                x/=i;
                k++;
                pk*=i;
            }
            if(k>0)
                ans=(ans+cal(n,m,p,i,pk))%p;
        }
        if(x>1)ans=(ans+cal(n,m,p,x,x))%p;
        return ans;
    }
    ll qtpow(ll x,ll y,ll M)
    {
        ll ret=0LL;
        for(x%=M;y;y>>=1LL)
        {
            if(y&1LL)
            {
                ret+=x;
                ret%=M;
                if(ret<0) ret+=M;
            }
            x+=x;
            x%=M;
            if(x<0) x+=M;
        }
        return ret;
    }
    void solve(ll r[],ll s[],int t)
    {
        ll M=1LL,ans=0LL;
        ll p[20],q[20],e[20];
        for(int i=0;i<t;i++)
            M*=r[i];
        for(int i=0;i<t;i++)
        {
            ll tmp=M/r[i],tt;
            extend_gcd(tmp,p[i],r[i],q[i]);
            p[i]%=M;
            if(p[i]<0) p[i]+=M;
            e[i]=qtpow(tmp,p[i],M);
            tt=qtpow(e[i],s[i],M);
            ans=(ans+tt)%M;
            if(ans<0) ans+=M;
        }
        printf("%I64d
    ",ans);
    }
    
    ll CCC[20],DDD[20];
    int main()
    {
        int t;
        scanf("%d",&t);
        int num = 0;
        ll n,m,p;
        while(t--)
        {
            memset(CCC,0,sizeof(CCC));
            memset(DDD,0,sizeof(DDD));
            scanf("%I64d %I64d %d",&n,&m,&num);
            for(int i=0;i<num;i++)
            {
                scanf("%I64d",&CCC[i]);
                DDD[i]=mCnmodp(n,m,CCC[i]);
            }
            solve(CCC,DDD,num);
        }
        return 0;
    }
  • 相关阅读:
    Spring-12-spring整合Mybatis
    Spring-11-AOP面向切面编程
    jQuery选择器之表单元素选择器
    phpsmarty分配变量
    angular
    ajax 第四步
    ajax第三步
    php+ajax+jq
    二十三种设计模式[4]
    二十三种设计模式[3]
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4805315.html
Copyright © 2011-2022 走看看