码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5407

时间:2015-10-02 18:34:27      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5407

题意:给定一个数n,求LCM(C(n,0),C(n,1),C(n,2)...,C(n,n))

根据官方题解,g(n) = LCM(C(n,0),C(n,1),C(n,2)...,C(n,n))

       g(n) = f(n+1)/(n+1)

     而    f(n) = LCM(1,2,3,...,n)

对于f(n)中的每一个数,对LCM的贡献值并不一样,可以想一下,对n进行因式分解,n = p1^x1*p2^x2*...+pt*xt;比n小的数中必然有p1^x1,p2^x2...

所以,只有当n可以分解为n=p^x的时候,才对LCM值有贡献。

#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long LL;
using namespace std;
const int mod = 1e9+7;
const int MAXN=1e6+10;
int prime[MAXN+1];
int ans[MAXN];
int fra[MAXN];
//  打印素数表
bool notprime[MAXN];//值为false表示素数,值为true表示非素数
void init1()
{
    memset(notprime,false,sizeof(notprime));
    notprime[0]=notprime[1]=true;
    for(int i=2;i<MAXN;i++)
        if(!notprime[i])
        {
            if(i>MAXN/i)continue;//防止后面i*i溢出(或者i,j用long  long)
            //直接从i*i开始就可以,小于i倍的已经筛选过了,注意是j+=i
            for(int j=i*i;j<MAXN;j+=i)
                notprime[j]=true;
    }
}
void getPrime()
{
    memset(prime,0,sizeof (prime));
    for(int i=2;i<=MAXN;i++)
    {
        if(!prime[i])prime[++prime[0]]=i;
        for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++)
        {
            prime[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
}
//  求逆元
long long inv(long long a,long long mod)
{
    if(a == 1)return 1;
    return inv(mod%a,mod)*(mod-mod/a)%mod;
}
void init2(){
    ans[1] = 1;
    int i, j;
    for( i = 2; i < MAXN; i++){
        int tmp = i+1;
        bool flag = false;
        for( j = 1; prime[j]*prime[j]<= i+1; ++j){
            while( tmp % prime[j] == 0 ){
                tmp /= prime[j];
                flag = true;
            }
            if(flag)
                break;
        }
        if(tmp == 1){
            ans[i] = 1LL*ans[i-1]*i%mod*prime[j]%mod*inv((i+1),mod)%mod;
        }
        else if(!notprime[i+1]){
            ans[i] = 1LL*ans[i-1]*i%mod*(i+1)%mod*inv((i+1),mod)%mod;
        }
        else{
            ans[i] = 1LL*ans[i-1]*i%mod*inv((i+1),mod)%mod;
        }
    }
}

int main(){
    getPrime();
    init1();
    init2();
    int T, N;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        printf("%d\n",ans[N]);
    }
    return 0;
}

hdu 5407

标签:

原文地址:http://www.cnblogs.com/blueprintf/p/4852490.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!