HDU 4196 Remoteland (数论 n!相关)

来源:互联网 发布:指纹膜淘宝 编辑:程序博客网 时间:2024/04/28 06:50

题意:用不大于n的所有正数去组成一个尽可能大的完全平方数。

思路:显然取n!是最大的,设其为a,但这不一定是一个完全平方数,需要把多余的部分除掉。

可以利用勒让德定理很快处理出n!所有素因子的指数,偶数保留,奇数-1,即可保证这些素因子最后乘积为完全平方数,也就是用a除以所有指数为奇数的素因子的乘积。注意由于有取模运算,所以不能直接除。

#include <cstdio>#include <cstring>const int mod=1000000007;const int N=10000005;int prime[670000],np=0;__int64 fac[N];bool tag[N];void Init (){int i,j;    for (i=2;i<N;i++) if (tag[i] == false)    {        prime[np++]=i;        for (j=i+i;j<N;j+=i)            tag[j]=true;    }fac[1]=1;for (i=2;i<N;i++)fac[i]=fac[i-1]*i%mod;}__int64 POW (__int64 s,__int64 index,__int64 mod){    __int64 ans=1;    s%=mod;    while (index>=1)    {        if ((index&1)==1)   //奇数            ans=(ans*s)%mod;        index>>=1;        s=s*s%mod;    }    return ans;}int Cal (int n,int p){int sum=0;while (n)sum+=(n/=p);return sum;}int main (){    int n;Init ();    while (scanf("%d",&n),n)    {__int64 ans=1;for (int i=0;i<np && prime[i]<=n;i++){int tmp=Cal(n,prime[i]);if (tmp&1)   //奇数ans=(ans*prime[i])%mod;}ans=fac[n]*POW(ans,mod-2,mod)%mod;printf("%I64d\n",ans);    }return 0;}



0 0