http://acm.hdu.edu.cn/showproblem.php?pid=4196
题目大意:
给你一个数字n,求不大于n能组成的最大的完全平方数。
解题思路:
完全平方数可以拆成不同的偶数个质数相乘,算出n!拆出来的各素数个数,奇数的就舍去一个,偶数的全要,然后再全部乘起来,快速求幂勉强能过。
关于快速求幂:http://blog.csdn.net/hkdgjqr/article/details/5381028
代码:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAXN 10000000
#define INF 0x7fffffff
#define eps 1e-10
#define MAX(x,y) ((x)>(y)? (x):(y))
#define MIN(x,y) ((x)<(y)? (x):(y))
#define MEM(a) (memset((a),0,sizeof(a)))
#define FRE freopen("input.txt","r",stdin)
using namespace std;
const int mod=1000000007;
int vis[10000010],prime[700000];
int main()
{
int cnt=0;
MEM(vis);
for(int i=2;i<=MAXN;i++)
{
if(!vis[i])
{
prime[cnt++]=i;
}
for(int j=0;j<cnt && prime[j]*i<=MAXN;j++)
{
vis[prime[j]*i]=1;
if(i%prime[j] == 0)
break;
}
}
int n;
while(scanf("%d",&n) && n)
{
long long ans=1;
for(int i=0;2*prime[i]<=n && i<cnt;i++)
{
long long temp=n;
int cut=0;
while(temp/prime[i]) //n!的素数拆分
{
temp/=prime[i];
cut+=temp;
}
if(cut%2) cut--;
temp=prime[i];
long long tempans=1;
while(cut)//快速求幂
{
if(cut&1)//奇数
{
tempans*=temp;
tempans%=mod;
}
temp*=temp;
temp%=mod;
cut>>=1;
}
ans=ans*tempans%mod;
}
printf("%lld\n",ans);
}
return 0;
}