题目大意:
数字$n$可以经过两个操作
$(1)$乘任意一个整数
$(2)$对该数字开根号,但需要保证该数字能被开尽
问最少经过上述操作多少次,可以让其变成无法再进行上述两个操作的最小数字。
分析:
受官方题解启发?一个数可以分解成$n=a_{1}^{p_{1}}\cdot a_{2}^{p_{2}}\cdot \cdot \cdot a_{n}^{p_{n}}$,所以我们实际需要的就是找到指数非0的$a_{i}$,而$\prod _{i=0}^{n} a_{i}$就是就是最小数字,而次数问题,因为数字可以分解成$n=a_{1}^{p_{1}}\cdot a_{2}^{p_{2}}\cdot \cdot \cdot a_{n}^{p_{n}}$,我们不从$n$开始算到最小数,而是从最小数算到$n$,这样的话开根号就变成了乘最小数字的一部分或是整个,然后实际上,我们并不需要管要乘以最小数的一部分还是整个,因为最后得到那个可以开尽的数一定满足$num \geq n$的,所以我们可以直接乘上整个最小数。最后在特判下$num$是不是大于$n$,如果大于,原本的数字$n$需要乘上最小数的一部分,所以操作次数也要加一次;否则则是刚刚好。
code:
#define frp
#include<bits/stdc++.h>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>
#include <string>
#include <string.h>
#include <iomanip>
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f;
const ll inf = 0x7fffff;
const int maxn = 2e6;
const int MAXN = 100000 + 5;
const int MOD = 1e9 + 7;
ll n,num=1,tot;
void solve() {
cin>>n;
tot=n;
for (int i = 2; i < n+1; ++i) {//通过枚举,得到最小分解底数
if(tot%i==0){
num*=i;
}
while(tot%i==0){
tot/=i;
}
}
int ans=0,tmp=num;
while(num%n){
num*=num;
ans++;
}
cout<<tmp<<" "<<(num>n?ans+1:ans)<<endl;
num=1;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef frp
freopen("D:\\coding\\c_coding\\in.txt", "r", stdin);
// freopen("D:\\coding\\c_coding\\out.txt", "w", stdout);
#endif
int t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}