hdu3826-Squarefree number-(欧拉筛+唯一分解定理)
Squarefree number
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3691 Accepted Submission(s):
971
Problem Description
In mathematics, a squarefree number is one which is
divisible by no perfect squares, except 1. For example, 10 is square-free but 18
is not, as it is divisible by 9 = 3^2. Now you need to determine whether an
integer is squarefree or not.
Input
The first line contains an integer T indicating the
number of test cases.
For each test case, there is a single line contains an integer N.
Technical Specification
1. 1 <= T <= 20
2. 2 <= N <= 10^18
For each test case, there is a single line contains an integer N.
Technical Specification
1. 1 <= T <= 20
2. 2 <= N <= 10^18
Output
For each test case, output the case number first. Then
output "Yes" if N is squarefree, "No" otherwise.
Sample Input
2
30
75
Sample Output
Case 1: Yes Case 2: No
翻译:输入一个n,如果可以被一个平方数整除,则不是平方自由数,输出no,否则输出yes
分析:显然要分解质因数,根据唯一分解定理分解。
n<=10^18,不能用暴力求到10^9的素数,欧拉筛一般只是找10^6内的素数。显然需要优化。
如果n>10^6,巨大,筛完了10^6内的质因子后,n还是大于10^6,则
1.如果n不是平方自由数,则因子中包含质因数的平方,则n=p*p,p是素数,p>10^6,除此之外没有别的大于10^6的因子了,否则n>10^18
2.如果n是平方自由数,则因子中不包含质因数的平方
(1)n是素数
(2)n不是素数,n=p1*p2,是两个大素数的乘积。p1,p2>10^6
1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<math.h> 6 #include<string> 7 #include<map> 8 #define ll long long 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 12 ll prime[1000086]; 13 ll cnt,t,n; 14 int maxx=1e6+5; 15 bool vis[1000086]; 16 17 18 void init() 19 { 20 memset(vis,true,sizeof(vis)); 21 vis[0]=vis[1]=false; 22 cnt=0; 23 for(ll i=2;i<=maxx;i++) 24 { 25 if(vis[i]) 26 prime[cnt++]=i; 27 for(ll j=0;j<cnt && i*prime[j]<=maxx;j++) 28 { 29 vis[ i*prime[j] ]=false; 30 if( i%prime[j]==0 ) break; 31 } 32 } 33 } 34 35 int main() 36 { 37 init(); 38 scanf("%lld",&t); 39 for(ll k=1;k<=t;k++) 40 { 41 bool flag=false; 42 scanf("%lld",&n); 43 for(ll i=0;i<cnt && !flag;i++) 44 { 45 int num=0; 46 while( n%prime[i]==0 )///分解质因子 47 { 48 n=n/prime[i]; 49 num++; 50 } 51 if(num>=2) 52 { 53 flag=true; 54 break; 55 } 56 } 57 /*分解完所有小于10^6的质因子,出来后的这个n还大于1的有三种情况 58 第一种情况,是一个 大于10^6 的素数 59 第二种情况,是两个 大于10^6 的素数 的乘积,不可能还有第三个大于10^6的质因子 60 第三种情况,是一个 大于10^6 的素数 的平方,不可能还有第三个大于10^6的质因子 61 */ 62 if(!flag && n>1) 63 { 64 ll temp=(ll)sqrt(n); 65 if(temp*temp==n) 66 flag=true; 67 } 68 if(flag) 69 printf("Case %lld: No\n",k); 70 else 71 printf("Case %lld: Yes\n",k); 72 } 73 return 0; 74 }