题目大意:给出一个数,判断其是否有含有平方因子

解题思路: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
 7using namespace std;
 8
 9int prime[80000];
10bool p[1000002];
11
12void 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
41int 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>1return -1;
56       if(n==1return 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
71int 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