질문의 의미 :
공지 된보다 큰 (\ 1 \) 정수 \ (P_1 = A ^ {^ {P_2 Q_2 Q_1}} \ cdots P_K q_k} ^ {\) 이제 주어진다 \ ([2,1e18]에서 \ \) 찾는 \ (최소 \ {Q_I \} Q \에서 [. 1, K] \) . 즉, 주요 인수 분해, 최소의 인덱스 번호를 찾는 후입니다.
아이디어 :
이후 \ ([2,1e18]에서 \ \) , 우리는 재생 \ (1E4의 \)를 소수 테이블 내의 다음 직접 획득 (1E4의 \하면) \ 내에있다.
그 위에 완료 할 수 있습니다, 대부분에 이제 \ (4 \) 다음과 같은 품질 요소 :
\ (N-4 = P \ ^) ,이 상황이되어 (4 \) \ 번
\ (N-P ^ = 3 \.) , 이 경우 세 번이다 \ (^ 3p_2 상기 n P_1 = \) 지시하고 마지막으로 응답
\ (상기 n P- 형 ^ 2 = \) , (* P_1 \ = p 형 P_1)는 \ 제 경우이다
(\ N = P의 \)
코드 :
#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 10000 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
using namespace std;
int prime[maxn], p[maxn], cnt;
void init(){
memset(p, 0, sizeof(p));
cnt = 0;
for(int i = 2; i < maxn; i++){
if(!p[i]){
prime[cnt++] = i;
}
for(int j = 0; j < cnt && i * prime[j] < maxn; j++){
p[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
bool triple(ll n){
ll l = 1e4, r = 1e6;
while(l <= r){
ll m = (l + r) >> 1;
ll ret = m * m * m;
if(ret == n) return true;
if(ret > n) r = m - 1;
else l = m + 1;
}
return false;
}
int main(){
int T;
init();
scanf("%d", &T);
while(T--){
ll n;
scanf("%lld", &n);
int ans = 1000;
for(int i = 0; i < cnt && prime[i] <= n; i++){
if(n % prime[i] == 0){
int num = 0;
while(n % prime[i] == 0){
num++;
n /= prime[i];
}
ans = min(ans, num);
}
}
if(n > 1 && ans > 1){
ll t1 = ll(sqrt(n));
ll t2 = ll(sqrt(t1));
if(t2 * t2 * t2 * t2 == n) ans = min(ans, 4);
else if(t1 * t1 == n) ans = min(ans, 2);
else if(triple(n)) ans = min(ans, 3);
else ans = 1;
}
printf("%d\n", ans);
}
return 0;
}