题目大意:给出一个数,判断其是否有含有平方因子
解题思路:1)10^18这是一个很大的数据,暴力是绝对不可行的。
2)如果其含有平方因子,则有n=a^2*b,这里的n<=10^18,所以a,b中必定有一个是小于10^6~。
3)筛10^6以内的素数,然后用n去除以这些质数的平方,如果能除,返回NO,否则,则看是否能够除以这个素数。
4)10^6以内的素数除光了,如果是1返回YES
5)剩下的也就只有三种可能,素数,素数的平方和,或者两个素数的积。
(证明:首先,剩下的肯定是比10^6大的素数,这个是毫无疑问的,而且这些素数因子的个数不可能超过3个,所以只有以上三种情况)
6)是两个素数的积返回NO,其他的YES
代码:
1
#include <cstdio>
2
#include <cstdlib>
3
#include <cmath>
4
#include <iostream>
5
#include <algorithm>
6
7
using namespace std;
8
9
int prime[80000];
10
bool p[1000002];
11
12
void PRIME(int M)
13

{
14
int i,i2,k;
15
for(i=0;i<=M;i+=2)
{ p[i]=0; }
16
for(i=1;i<=M;i+=2)
{ p[i]=1; }
17
p[2]=1;
18
p[1]=0;
19
for(i=3;i<=1000;i+=2)
20
{
21
if(p[i]==1)
22
{
23
i2=i+i;
24
k=i*i;
25
while(k<=M)
26
{
27
p[k]=0;
28
k+=i2;
29
}
30
}
31
}
32
prime[1]=2;
33
k=1;
34
for(i=3;i<=M;i+=2)
35
if(p[i]) prime[++k]=i;
36
prime[0]=k;
37
return ;
38
}
39
40
41
int Int(long long n)
42

{
43
int i,s,k;
44
long long d,e;
45
k=0;
46
for(i=1;i<=prime[0];i++)
47
{
48
s=0;
49
while(n%prime[i]==0)
50
{
51
s++;
52
n/=prime[i];
53
}
54
55
if(s>1) return -1;
56
if(n==1) return 1;
57
if(n/prime[i]<prime[i]) return 1;
58
}
59
d=(long long)sqrt((double)n);
60
d--;
61
while(1)
62
{
63
e=d*d;
64
if(e==n)return -1;
65
if(e>n)break;
66
d++;
67
}
68
return 1;
69
}
70
71
int main()
72
{
73
int T,i,k;
74
long long N,d;
75
PRIME(1000000);
76
scanf("%d",&T);
77
for(i=1;i<=T;i++)
78
{
79
scanf("%I64d",&N);
80
k=Int(N);
81
if(k==1) printf("Case %d: Yes\n",i);
82
else printf("Case %d: No\n",i);
83
}
84
return 0;
85
}
86
87