lucas Theorem (template title explanations)

 

The questions were very simple, very violent, is a combination of numbers, there is no other.

But direct violence will explode wow

We can use the word Lucas theorem decomposition problem.

Lucas定理:C(n,m)(mod p)=C(n%p,m%p)*C(n/p,m/p)(mod p);

So, we can put this topic broken down into sub-problems:

C(n,m+n)(mod p)=C(n%p,m+n%p)*C(n/p,(m+n)/p);

C and the second and Lucas Theorem method can be used,

It can be recursively solved

When when m = 0, Lucas returns 1 (C (n, 0) = 1)

However, still have to pay attention to:

To reverse this problem yuan! ! !

To reverse this problem yuan! ! !

To reverse this problem yuan! ! !

Because the combination to divide, it is necessary to inverse.

Fortunately topic cordial, p must be a prime number, so the direct Fermat's little get.

Thus: O (n) factorial process, logn inverse processing (card speed m) lognLucas

So overall complexity should be O (Tnlog ^ 2n) (not to be)

Paste the code, some precautions written in code

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
long long n,m,p;
long long ksm(long long a,long long b)
{
    a%=p;
    long long res=1;
    while(b)
    {
        if(b%2==1)
        res=(res*a)%p;
        a=(a*a)%p;
        b>>=1; 
    } 
    Return RES; 
} 
Long  Long FAC [MAXN];
 Long  Long C ( Long  Long A, Long  Long B) 
{ 
    IF (A < B) // pits, if the total number is less than the program (C (n, m) n <m, it is not selected) to get out of
     return  0 ;
     return (FAC [A] * KSM (FAC [B], p- 2 )) P * KSM% (FAC [ab &], p- 2 )% P; // inverse multiplication, the number of combinations 
} 

Long  Long Lucas ( Long  Long A, Long  Long B) 
{ 
    IF (B == 0 )
    return 1;
    return lucas(a/p,b/p)*C(a%p,b%p)%p;//Lucas表达
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&n,&m,&p);
        fac[0]=1;//阶乘
        for(long long i=1;i<=p;i++)
        {
            fac[i]=(fac[i-1]*i)%p; // factorial 
        } 
        the printf ( " % LLD \ n- " , Lucas (+ n- m, n-)); // run Lucas 
    } 
    return  0 ; 
}

(Finish)

 

 

Guess you like

Origin www.cnblogs.com/ajmddzp/p/11235146.html