hdu5407

首先对于要模一个数的题来说,最后,答案一般可以化成一个式子,比如想这道题,如果用传统的方法来算最小公倍数的话,是没办法达到这个要求的,所以应该经过某种变形,至于这种变形会不会,那就只能凭运气了,我是没运气的那种,丰富的只是积累才能带来好的运气!吐舌头,大概的证明方法如下。

Legendre's formula

用来求n!因式分解后有多少个p(p为任意一个素数),换种说法就是求,p^i整除n!这个i最大是多少。

Proof:

Since  is the product of the integers 1through n, we obtain atleast one factor of p in  for each multiple of p in , of whichthere are .Each multiple of  contributes an additional factor of p, each multiple of  contributes yet another factor of p, etc. Adding up the number ofthese factors gives the infinite sum for . The sum contains onlyfinitely many nonzero terms, since  for .

Toobtain the second form, write  in base p. Then , and therefore

Kummer Theorem

In mathematicsKummer'stheorem on binomial coeffients gives the highest power of a prime number p dividing a binomialcoefficient. In particular, it asserts that given integers n ≥ m ≥ 0 anda prime number p, the maximuminteger k such that pk divides the binomial coefficient  is equal to the number of carries when m is added ton − m in base p.

mn为正整数,p为素数,则C(m+nm)p的幂次等于m+np进制下的进位次数。

组合数所含p的幂次数为

  = 

这是因为组合数公式  以及n!含有素数p的幂次公式vp(n!) = 对于某个p^i等于mp进制表示下去掉后i位,在第i+1位上,m+n在这一位上进位的充要条件是=1,不进位则 =0.因此 就是m+np进制下的进位次数。

然后接下来看了这篇文章http://arxiv.org/pdf/0906.2295v2.pdf 就能明白了。

参考链接:

https://en.wikipedia.org/wiki/Legendre%27s_formula

https://en.wikipedia.org/wiki/Kummer%27s_theorem

http://baike.baidu.com/link?url=Hf8nIk-2bh6zZesAS2K0zASowm6sW6u2ETH37m3DDAA-1-pwGB3UIL2LgtN4U4oh2rtWi2wU715rEiTu0mBa0_UV0kqgwWXKoPhvxWUw_nskIYr7He4uyONUT_KVbRYF

(今天不说吃的,说点严肃的话题,一直以为,只要代码是自己写的,就算原创,可是看了别人的博客以后,才发现,算是转载吧,所以今天把有链接的从原创改成了转载)

2015.8.29:

今天把这道题又想了一遍,感觉虽然读的是英文版的证明,但是比中文版的简单好多,怪不得老师总是推荐我们看英文版的原著。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 1000010
#define MOD 1000000007

int divz[N];
int divnum[N];
int pownum[N];
long long int lcm[N];

int pow(int x,int y){
    long long int tempx=x;
    long long int ans=1;

    while(y){
        if(y%2){
            ans=ans*tempx%MOD;
        }
        y=y/2;
        tempx=tempx*tempx%MOD;
    }

    return (int)ans;
}

int main(){
    for(int i=2;i<N;i++){
        if(divnum[i]==0){
        divz[i]=i;
        divnum[i]=1;
            for(int j=i+i;j<N;j=j+i){
                divnum[j]++;
                divz[j]=i;
            }
        }
    }

    lcm[1]=1;
    for(int i=2;i<N;i++){
        if(divnum[i]==1){
            lcm[i]=lcm[i-1]*divz[i]%MOD;
        }
        else{
            lcm[i]=lcm[i-1];
        }
    }

    int t;
    int n;

    scanf("%d",&t);
    //printf("%d\n",pow(1,MOD-2));
    while(t--){
        scanf("%d",&n);
        printf("%lld\n",lcm[n+1]*pow(n+1,MOD-2)%MOD);
    }

    return 0;
}


posted @ 2015-08-21 15:14  buzhidaohahaha  阅读(254)  评论(0编辑  收藏  举报