您的位置:首页 > 其它

HDU 3826 Squarefree number (求因子里没有平方数的数)

2014-05-20 00:52 363 查看
此题初看很头疼10^18的数,要用筛法至少要10^9以下的素数,也太大了,故肯定有玄机。先只考虑素数因子,因为如果是某个数的因子不是素数且是平方数,则该因子的素因数的平方也属于这个数的因子,所以只需要考虑素数因子就可以了。继续刚才说的,如果要是有平方因子的,那么这个因子必须要小于10^9,不然肯定超过10^18, 再考虑一下,对于筛素数,我们只能筛到10^6,10^7可以说已经是极限了,小于10^6的数,可以直接一个个试,对于同一个数可以连续整除2次以上就是有平方因子的数,对于10^6到10^9之间的素因数应该怎么办?答案是,当这个数的素因子已经大于10^6了后,他的素因子最多只有2个了,不然3个大于10^6的数乘起来肯定大于10^18了。那么这2个数若不一样,那么就因子里没有平方数。方法很明朗了,不过要注意一点,要筛至少10^6以下的素数,因为如果只有10^5,那么可能该数还有3个素因子,就不能用刚才的方法判断是否因子里没有平方数了。

PS:在HDU上没做几道题。。还不知道是用__int64。。害得我用long long WA了N次。。

AC代码:

#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<ctime>
using namespace std;
#define NMAX 1000000
#define ll __int64
#define eps 1e-6
int prime[80000];
bool vis[NMAX];
int getprime()
{
int i,j,k;
memset(vis,0,sizeof(vis));
for(k = 0,i = 2; i <= NMAX; i++)
if(!vis[i])
{
prime[k++] = i;
for(j = i; (ll)i*j <= NMAX; j++)
vis[j*i] = 1;
}
return k;
}

int main()
{
//    freopen("input.txt","r",stdin);
//    freopen("o1.txt","w",stdout);
int k = getprime();
int t,i;
ll n;
scanf("%d",&t);
int tt = t;
while(tt--)
{
int nct;
bool flag = 0;
scanf("%I64d",&n);
for(i = 0; i < k && n >= prime[i]; i++)
{
nct = 0;
while(n%prime[i] == 0)
{
n /= prime[i];
nct++;
}
if(nct >= 2)
{
flag = 1;
break;
}
}
if(n == 1 && flag != 1)
{
printf("Case %d: Yes\n",t-tt);
continue;
}
double x = sqrt(n+0.0);
if((ll)x*(ll)x == n) flag = 1;
if(flag) printf("Case %d: No\n",t-tt);
else printf("Case %d: Yes\n",t-tt);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: