1. 程式人生 > 實用技巧 >牛客挑戰賽46 B 最小的指數

牛客挑戰賽46 B 最小的指數

給出一個數\(x\),將它分解質因數成\(\prod p_i^{a_i}(a_i>0)\),求\(\min(a_i)\)

\(T\le 10^5\)

\(x\le 10^{18}\)


pollard-rho顯然過不去。

先將\(4000\)以內的質數都暴力做一遍,如果遇到了\(x\)的因數計算一下。

對於剩餘的質數,\(ans\)不會大於等於\(5\),因為\(4000^5>10^{18}\)

那麼\(ans\in \{4,3,2,1\}\),分別判一下答案是不是完全\(ans\)次方數即可。

可以證明沒有\(ans\ge 2\)並且\(x\)不是完全\(ans\)次方數的情況:發現這個情況下,\(x\)

至少可以表示成\(p_1^2p_2^3\)的形式。這時候已經超過了範圍。

時間複雜度\(O(T|4000以內質數|)\)


using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
#define N 4005
ll n;
int p[N],np;
bool inp[N];
ll qpow(ll x,ll y){
	ll r=1;
	for (;y;y>>=1,x=x*x)
		if (y&1)
			r=r*x;
	return r;
}
bool check(ll n,int k){
	ll x=pow(n,1.0/k);
	return qpow(x-1,k)==n || qpow(x,k)==n || qpow(x+1,k)==n;
}
void initp(int n){
	for (int i=2;i<=n;++i){
		if (!inp[i])
			p[++np]=i;
		for (int j=1;j<=np && i*p[j]<=n;++j){
			inp[i*p[j]]=1;
			if (i%p[j]==0)
				break;
		}
	}
}
ll m;
bool part1(){
	for (int i=1;i<=np;++i){
		if (n%p[i]==0){
			ll k=0;
			while (n%p[i]==0)
				++k,n/=p[i];
			m=min(m,k);
		}
	}
	return n==1;
}
ll part2(){
	if (check(n,4))
		return 4;
	if (check(n,3))
		return 3;
	if (check(n,2))
		return 2;
	return 1;
}
int main(){
	freopen("in.txt","r",stdin);
	initp(4000);
	int T;
	scanf("%d",&T);
	while (T--){
		scanf("%lld",&n);
		if (n==1){
			printf("0\n");
			continue;
		}
		m=100;
		if (!part1())
			m=min(m,part2());
		printf("%lld\n",m);
	}
	return 0;
}