Codeforces Round #520 (Div. 2) B. Math 唯一分解定理+贪心

题意:给出一个x 可以做两种操作  ①sqrt(x)  注意必须是完全平方数  ② x*=k  (k为任意数)  问能达到的最小的x是多少

思路: 由题意以及 操作  应该联想到唯一分解定理   经过分析可以知道   ②操作最多使用一次  将x分解成一系列素数乘积的时候  只要看最高幂次离哪个二的幂近(只取上界)  

并且把所以素因子都凑成找到的这个二的幂  只要x*=k一步就可以凑成  然后一直操作①模拟即可 而如果刚好全部都相等并且都是2的幂次 那么直接一直操作①模拟即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e6+5;
 5 int fac[maxn],mi[maxn];
 6 int solve(int x){
 7     ll tmp=1;
 8     for(int i=0;;i++){
 9         if(tmp>=x){
10             return i;
11         }
12         else tmp<<=1;
13     }
14 }
15 map<ll,int>mp;
16 int main(){
17     int n;
18     scanf("%d",&n);
19     ll la=1;
20     for(int i=1;i<=1000;i++){
21             la<<=1;
22             if(la>10000000)break;
23             mp[la]=1;
24     }
25     if(n==1){
26         cout<<1<<" "<<0<<endl;
27         return 0;
28     }
29     int flag=1;
30     long long ans=1;
31     for(int i=2;i<=n;i++){
32         if(n%i==0){
33             fac[flag]=i;
34             ans*=i;
35             while(n%i==0){
36                 n/=i;
37                 mi[flag]++;
38             }
39             flag++;
40         }
41     }
42     int maxnum=0;
43     int cnt=0;
44     int ok=0;
45     for(int i=1;i<flag;i++){
46         maxnum=max(maxnum,mi[i]);
47         if(mp[mi[i]]!=1)ok=1;
48         if(i>1&&mi[i]!=mi[i-1])ok=1;
49     }
50     if(maxnum==1){
51         cout<<ans<<" " <<0<<endl;
52         return 0;
53     }
54     if(maxnum&1)maxnum++;
55     if(ok)cnt++;
56 //    cout<<maxnum<<endl;
57     cnt+=solve(maxnum);
58     cout<<ans<<" "<<cnt<<endl;
59     return 0;
60 }
View Code

猜你喜欢

转载自www.cnblogs.com/ttttttttrx/p/10790820.html