题意:用不大于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;
}