HDU 6623 Minimal Power of Prime(数学)

传送门

•题意

  给你一个大于 1 的正整数 n;

  它可以分解成不同的质因子的幂的乘积的形式,问这些质因子的幂中,最小的幂是多少。

•题解

把[1,10000]内的素数筛出来,然后对于每个素$P$数遍历找$P_{k}$的$k$,用$ans$来维护最小的$k$

对于大于10000的素数,$(10^{4})^{4}<10^{18}<(10^{4})^{5}$,所以最大是4次方

先看4次方:

若$x^{4}==n$,则$x$一定是素数,为什么是素数?

根据欧拉定理,一个数可以分成若干个素数乘积的形式。如$m=p_{1}^{k1}\cdot p_{2}^{k2}\cdot p_{3}^{k3}\cdot p_{4}^{k4}\cdot p_{5}^{k5}$

假设$p_{1},p_{2},p_{3}$为$10000$以内的素数,$p_{4},p_{5}$为大于$10000$的素数。

由于$n$的$10000$以内的素数都被消去了,现只剩下$p_{4}^{k4}\cdot p_{5}^{k5}=n$

因为$p_{4}^{k4}\cdot p_{5}^{k5}=n=x^{4}$,由上只上限是4, 为了方便设$k4=k5=4$,所以$p_{4}^{4}\cdot p_{5}^{4}$可以合并为$(p_{4}p_{5})^{4}$,也就是$x=(p_{4}p_{5})$这个合数。

但是$p_{4},p_{5}$都是$>10^{4}$,所以$x=(p_{4}p_{5})>10^{8}$,即$n=x^{4}=(p_{4}p_{5})^{4}>10^{18}$,与题意矛盾

再看2次方

若$x^{2}==n$,则$x$可能是合数可能是素数?

  如果是4次方的话肯定不能是2次方,由上只$x$是个素数,那$y=x^{2}$的话,$y$就是合数了,所以2次方4次方只能存在一个

如果不是4次方的话,可以是2次方有两种情况,$x$是素数和$x$是合数,素数符合是明显的,那合数为什么符合呢

仍然以上述例子$m=p_{1}^{k1}\cdot p_{2}^{k2}\cdot p_{3}^{k3}\cdot p_{4}^{k4}\cdot p_{5}^{k5}$

假设$p_{1},p_{2},p_{3}$为$10000$以内的素数,$p_{4},p_{5}$为大于$10000$的素数。

由于$n$的$10000$以内的素数都被消去了,现只剩下$p_{4}^{k4}\cdot p_{5}^{k5}=n$

因为$p_{4}^{k4}\cdot p_{5}^{k5}=n=x^{2}$,由上面上限是4同理知上限是2,为了方便设$k4=k5=2$,所以$p_{4}^{2}\cdot p_{5}^{2}$可以合并为$(p_{4}p_{5})^{2}$,也就是$x=(p_{4}p_{5})$这个合数。对于$p_{4}^{2}$这个素数来说是2,对于$p_{5}^{2}$这个素数来说也是2,对于$(p_{4}p_{5})^{2}$这个合数可以分成$p_{4}^{2} p_{5}^{2}$这两个素数,也是2.

3次方与4次方同理

如果都不是的话,就只剩下一个素数了,那就是1

•代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn=1e4;
 5 const int mmaxn=1e6;
 6 int prime[maxn];
 7 bool Mark[maxn+50];
 8 int num;
 9 void Prime()
10 {
11     for(int i=2;i<=maxn;i++)
12     {
13         if(Mark[i]==0)
14             prime[num++]=i;
15         for(int j=0;j<num&&prime[j]*i<=maxn;j++)
16         {
17             Mark[i*prime[j]]=1;
18             if(i%prime[j]==0)
19                 break;
20         }
21     }
22 }
23 int main()
24 {
25     Prime();
26     int T;
27     scanf("%d",&T);
28     while(T--)
29     {
30         ll n;
31         scanf("%lld",&n);
32         int ans=100;
33         for(int i=0;i<num;i++)
34         {
35             int cur=0;
36             while(n%prime[i]==0)
37             {
38                 n/=prime[i];
39                 cur++;
40             }
41             if(!cur)
42                 continue;
43             ans=min(ans,cur);
44             if(ans==1||n==1)
45             {
46                 printf("%d\n",ans);
47                 break;
48             }
49         }
50         if(ans==1||n==1)
51             continue;
52 
53         ll x=sqrt(sqrt(n));
54         ll y=sqrt(n);
55         
56         if(x*x*x*x==n)///4
57             ans=min(ans,4);
58         else if(y*y==n)///2
59             ans=2;
60         else///3
61         {
62             bool flag=false;
63             ll l=maxn-1,r=mmaxn+1;
64             while(r-l>1)
65             {
66                 ll mid=(l+r)>>1;
67                 if(mid*mid*mid>n)
68                     r=mid;
69                 else
70                     l=mid;
71                 if(mid*mid*mid==n)
72                 {
73                     flag=true;
74                     ans=min(ans,3);
75                     break;
76                 }
77             } 
78             if(!flag)
79                 ans=1;
80         }
81         printf("%d\n",ans);
82     }
83 }
View Code

 

posted @ 2019-10-20 21:32  MMMinoz  阅读(159)  评论(0编辑  收藏  举报