1. 程式人生 > >CF 520 div.2 B. Math

CF 520 div.2 B. Math

gif one pla turn opened std lowbit ack ons

題意:給定數n,可進行兩種操作:乘一個任意數x; 開方,( sqrt(n)必須為整數

輸出可達最小值ans 及 最小操作數

  一個數可分解成有限個質數的冪次相乘:n=p1^x1 * p2^x2 * p3^x3..., 則n的所有質因子的乘積即為ans

  接下來就是找所有質因子和判斷最小操作數了

  從 i=2 開始 n的第一個因子必為質數,不斷除該因子,減小n, 新得到n的第一個因子也必為質數, 重復,直至 i==n

咋找最小操作數捏,e.g. 40=2^3*5^1; ans=10, 能開方次數必為2的冪次, 這裏冪次最大為3, 則要開方至少得*2得到2^4

  so 問題解決了 最小操作數就是開方次數+乘數的次數

  

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<list>
#include
<set> using namespace std; typedef long long ll; typedef pair<ll,ll> p; typedef long double ld; #define mem(x) memset(x, 0, sizeof(x)) #define me(x) memset(x, -1, sizeof(x)) #define fo(i,n) for(i=0; i<n; i++) #define sc(x) scanf("%lld", &x) #define pr(x) printf("%lld\n", x) #define
pri(x) printf("%lld ", x) #define lowbit(x) x&-x const ll MOD = 1e18 +7; const ll N = 6e6 +5; map<ll,ll>mp; ll a[N]; int main() { ll i, j ,k, l=0; ll n, m, t; cin>>n; if(n==1) return cout<<1<< <<0<<endl, 0; ll ans=1, mx=0, mi=MOD; m=0; for(i=2; i<=n; i++) { ll co=0; if(n%i==0) ans*=i; while(n%i==0) n/=i, co++; mx=max(co,mx); if(co) { mi=min(mi,co); } while((1<<m)<co) m++; } //cout<<"m="<<m<<" mx="<<mx<<" mi="<<mi<<endl; if(mi!=mx || (1<<m)!=mx) m++; cout<<ans<< <<m<<endl; return 0; }
View Code

  

CF 520 div.2 B. Math