【数学-求组合数的最小公倍数】HDOJ CRB and Candies 5407

CRB and Candies

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 847    Accepted Submission(s): 406


Problem Description
CRB has  N  different candies. He is going to eat  K  candies.
He wonders how many combinations he can select.
Can you answer his question for all  K (0 ≤  K  ≤  N )?
CRB is too hungry to check all of your answers one by one, so he only asks least common multiple(LCM) of all answers.
 

Input
There are multiple test cases. The first line of input contains an integer  T , indicating the number of test cases. For each test case there is one line containing a single integer  N .
1 ≤  T  ≤ 300
1 ≤  N  ≤  106
 

Output
For each test case, output a single integer – LCM modulo 1000000007( 109+7 ).
 

Sample Input
   
   
   
   
5 1 2 3 4 5
 

Sample Output
   
   
   
   
1 2 3 12 10
 

Author
KUT(DPRK)
 

Source
2015 Multi-University Training Contest 10
 


题意:

求LCM{ C (n,1), C(n,2), C(n,3),C(n,4).....C(n,n) }

解题思路;

竟然有 OEIS 这种神器存在!依据公式有:LCM{C (n,1), C(n,2), C(n,3),C(n,4).....C(n,n) }=LCM{1,2,3,4,.......n+1}/n+1。

LCM{1,2,3,4,......n}的计算也有公式~如果n有一个素数p使n=p^k,则a(n)=p*a(n-1),否则a(n)=a(n-1)。然后就非常简单了~记得求逆元。

AC代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

const int MAXN=1000000+10;
const int Mod=1000000007;

typedef long long LL;

LL a[MAXN];
bool is_prime[MAXN];
LL prime[MAXN];
LL f[MAXN];

void init()
{
    int tot=0;
    is_prime[0]=is_prime[1]=true;
    for(int i=2;i<MAXN-1;i++){
        if(!is_prime[i]){
            prime[tot++]=i;
            for(int j=i*2;j<MAXN;j+=i){
                is_prime[j]=true;
            }
        }
    }
    for(int i=0;i<tot;i++){
        LL temp=prime[i];
        LL p=prime[i];
        while(temp<MAXN){
            a[temp]=p;
            temp*=p;
        }
    }
    f[1]=1;
    for(int i=2;i<MAXN-5;i++){
        if(a[i]) f[i]=a[i]*f[i-1]%Mod;
        else f[i]=f[i-1]%Mod;
    }
}

LL exgcd(LL a,LL b,LL &x,LL &y)
{
    LL d=a;
    if(b){
        d=exgcd(b,a%b,y,x);
        y=y-(a/b)*x;
    }
    else{
        x=1;y=0;
    }
    return d;
}

LL mod_reverse(LL a,LL n)
{
    LL x,y;
    LL d=exgcd(a,n,x,y);
    if(d==1) return(x%n+n)%n;
    return -1;
}

int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--){
        LL n;
        scanf("%lld",&n);
        LL d=mod_reverse(n+1,(LL)Mod);
        printf("%lld\n",f[n+1]*d%Mod);
    }
    return 0;
}


你可能感兴趣的:(【数学-求组合数的最小公倍数】HDOJ CRB and Candies 5407)