HDU6623 Minimal Power of Prime (简单数论)

题面

T ≤ 50   000 T\leq50\,000 T50000 组数据:

输入一个数 N N N 2 ≤ N ≤ 1 0 18 2\leq N\leq 10^{18} 2N1018),输出一个数,表示 N N N 质因数分解后,每个质因数的幂的最小值。

题解

妙妙题!

一种神奇的做法:

我们把 N 5 < 3   982 \sqrt[5]{N}<3\,982 5N <3982 以内的质数都筛出来,以便把 N N N ≤ N 5 \leq\sqrt[5]{N} 5N 的质因数都找到,统计次数,处理答案。然后把 N N N 里面的这些质因子全部除掉。这一步的时间大概在 500 左右。

用反证法,不难证明剩下的 N N N 最多只有 4 质因数,所以,要么存在质因数的幂为 1 (答案输出 1),如果不存在,要么是某个质数的平方,要么是三次方、四次方,这三者都可以求出 N 2   ,   N 3   ,   N 4 \sqrt[2]{N}~,~\sqrt[3]{N}~,~\sqrt[4]{N} 2N  , 3N  , 4N 然后 O ( 1 ) O(1) O(1) 判断。

CODE

#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 10005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
	LL f = 1,x = 0;char s = getchar();
	while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
	while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
	return f * x;
}
int n,m,i,j,s,o,k;
int MOD = 1;
inline LL safemul(LL a,LL b,LL MOD) {
	return a*b%MOD;
//	LL nm = a*b-((LL)((long DB)a/MOD*b+0.5)*MOD);
//	return (nm%MOD+MOD)%MOD;
}
LL qkpow(LL a,LL b,LL MOD) {
	LL res = 1;
	while(b > 0) {
		if(b & 1) {
			if(res*a >= MOD) res = safemul(res,a,MOD)+MOD;
			else res = safemul(res,a,MOD);
		}
		if(a * a >= MOD) a = safemul(a,a,MOD)+MOD;
		else a = safemul(a,a,MOD);
		b >>= 1;
	}return res;
}
LL L;
LL PHI(LL x) {
	LL as = x;
	for(int i = 2;i *1ll* i <= x;i ++) {
		if(x % i == 0) {
			as = as/i*(i-1);
			while(x % i == 0) x /= i;
		}
	}
	if(x > 1) as = as / x * (x-1);
	return as;
}
bool comp(LL a,LL b,LL c) {
	LL res = 1;
	for(int i = 1;i <= b;i ++) {
		if(res > c/a) return 1;
		res = res * a;
	}return res > c;
}
int p[MAXN],cnt;
bool f[MAXN];
void sieve(int n) {
	for(int i = 2;i <= n;i ++) {
		if(!f[i]) p[++ cnt] = i;
		for(int j = 1;j <= cnt && i*p[j] <= n;j ++) {
			f[i*p[j]] = 1;
			if(i%p[j] == 0) break;
		}
	}return ;
}
int depcheck(int tm,LL &MOD) {
	int ans = 64;
	for(int ii = 1;ii <= cnt;ii ++) {
		int i = p[ii];
		if(MOD % i == 0) {
			int ct = 0;
			while(MOD % i == 0) MOD /= i,ct ++;
			ans = min(ans,ct);
		}
	}
	return ans;
}
int main() {
	sieve(4000);
	int T = read();
	while(T --) {
		LL N = read();
		int as = depcheck(5,N);
		LL y4 = (LL)(pow((DB)N,0.25)+0.1);
		LL y3 = (LL)(pow((DB)N,1.0/3.0)+0.1);
		LL y2 = (LL)(sqrt((DB)N)+0.1);
		if(N > 1) {
			if(y4*y4*y4*y4 == N) as = min(as,4);
			else if(y3*y3*y3 == N) as = min(as,3);
			else if(y2*y2 == N) as = min(as,2);
			else as = 1;
		}
		printf("%d\n",as);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值