您的位置:首页 > 其它

完全平方数

2016-02-28 19:57 399 查看
题目描述

一个数如果是另一个整数的完全平方,那么我们就称这个数为完全平方数(Pefect Sqaure),也称平方数。

小A认为所有的平方数都是很perfect的~

于是他给了小B一个任务:用任意个不大于n的不同的正整数相乘得到完全平方数,并且小A希望这个平方数越大越好。

请你帮助小B告诉小A满足题意的最大的完全平方数。

输入

输入文件名为number.in

输入仅 1行,一个数n。

输出

输出文件名为number.out

输出仅1行,一个数表示答案。由于答案可以很大,所以请输出答案对100000007取模后的结果。

【样例1】

number.in

7

number.out

144

【样例解释1】

144=2×3×4×6,是12的完全平方。

【样例2】

number.in

9

number.out

5184

【样例解释2】

5184=3×4×6×8×9,是72的完全平方。

提示

【数据范围】

对于20%的数据,0<n≤100;

对于50%的数据,0<n≤5,000;

对于70%的数据,0<n≤100,000;

对于100%的数据,0<n≤5,000,000。

来源

2013学军中学noip模拟day2

solution:要生成一个完全平方数,它必定是由2的偶数次方*3的偶数次方*5的偶数次方。。。。。。等等质数的偶数次方。因此我们可以很自然地想到分解质数,那么怎么求出500万之内的质数呢?普通的一个个枚举太慢,只能用筛法。其次,我们就要2--n中所有质数的次方数了,也就是一一分解它们,那么我们最后求答案要怎么求呢?如果碰到某个质数是奇数次方,该怎么办?其实很简单,直接把那个光杆质数扔掉就行了阿!

但是,一测大数据,我发现超时超得一塌糊涂,再调了一下,发现500万的质数有34万多个,如果一个一个唯一分解,到了一些大数的时候,每个都要遍历几十万个质数,还不爆?

后来,sk大神告诉了我他百度来的方法,直接用n除每个质数,然后加上每次剩下的即可,为何可以这样?我来举个例子:用9除2:

4 1——n中唯一分解中有1个2的有4个数

2 有2个2

1 有3个2

这样就能快速算出每个质数有几次方了。Orz。。。。。。。

第一次超%30的代码

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int m=100000007;
int n,l;
long long ans;
int p[5000005],a[350000],b[350000];
int main()
{
ans=1;
cin>>n;
int x=int(sqrt(n));
for(int i=2;i<=x;i++)
if(p[i]==0)
{
int y=n/i;
for(int j=2;j<=y;j++) p[i*j]=1;
}
for(int i=2;i<=n;i++)
if(p[i]==0)
{
l++;
a[l]=i;
}
for(int i=2;i<=n;i++)
{
int x=i;
int k=0;
while(x!=1)
{
k++;
while(x%a[k]==0)
{
x=x/a[k];
b[k]++;
}
}
}
for(int i=1;i<=l;i++)
{
if(b[i]%2==1) b[i]--;
for(int j=1;j<=b[i];j++) ans=(ans*a[i])%m;
}
cout<<ans<<endl;
return 0;
}
AC的代码

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int m=100000007;
int n,x,l;
long long ans;
int p[5000005],a[350000],b[350000];
int main()
{
ans=1;
cin>>n;
x=int(sqrt(n));
for(int i=2;i<=x;i++)
if(p[i]==0)
{
int y=n/i;
for(int j=2;j<=y;j++) p[i*j]=1;
}
for(int i=2;i<=n;i++)
if(p[i]==0)
{
l++;
a[l]=i;
}
for(int i=1;i<=l;i++)
{
x=n;
while(x/a[i]>0)
{
x=x/a[i];
b[i]=b[i]+x;
}
}
for(int i=1;i<=l;i++)
{
if(b[i]%2==1) b[i]--;
for(int j=1;j<=b[i];j++) ans=(ans*a[i])%m;
}
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: