题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6623
5 2 12 108 36 65536
1 1 2 2 16
#include
#define INF 0x3f3f3f3f
#define ll long long
#define LL long long
using namespace std;
LL Mult_Mod(LL a, LL b, LL m) { //res=(a*b)%m
a %= m;
b %= m;
LL res = 0;
while(b) {
if(b & 1)
res = (res + a) % m;
a = (a <<= 1) % m;
b >>= 1;
}
return res % m;
}
LL Pow_Mod(LL a, LL b, LL m) { //res=(a^b)%m
LL res = 1;
LL k = a;
while(b) {
if((b & 1))
res = Mult_Mod(res, k, m) % m;
k = Mult_Mod(k, k, m) % m;
b >>= 1;
}
return res % m;
}
bool Witness(LL a, LL n, LL x, LL sum) {
LL judge = Pow_Mod(a, x, n);
if(judge == n - 1 || judge == 1)
return 1;
while(sum--) {
judge = Mult_Mod(judge, judge, n);
if(judge == n - 1)
return 1;
}
return 0;
}
bool Miller_Rabin(LL n) {
if(n < 2)
return 0;
if(n == 2)
return 1;
if((n & 1) == 0)
return 0;
LL x = n - 1;
LL sum = 0;
while(x % 2 == 0) {
x >>= 1;
sum++;
}
int times = 5; /// 随机化次数
for(LL i = 1; i <= times; i++) {
LL a = rand() % (n - 1) + 1; //取与p互质的整数a
if(!Witness(a, n, x, sum)) //费马小定理的随机数检验
return 0;
}
return 1;
}
LL GCD(LL a, LL b) {
return b == 0 ? a : GCD(b, a % b);
}
LL Pollard_Rho(LL n, LL c) { //寻找一个因子
LL i = 1, k = 2;
LL x = rand() % n; //产生随机数x0(并控制其范围在1 ~ x-1之间)
LL y = x;
while(1) {
i++;
x = (Mult_Mod(x, x, n) + c) % n;
LL gcd = GCD(y - x, n);
if(gcd < 0)
gcd = -gcd;
if(gcd > 1 && gcd < n)
return gcd;
if(y == x)
return n;
if(i == k) {
y = x;
k <<= 1;
}
}
}
unordered_map<ll, int> pcnt;
unordered_map<ll, bool> isp;
void Find_fac(LL n) { //对n进行素因子分解,存入factor
if(isp[n] || Miller_Rabin(n)) { //是素数就把这个素因子存起来
isp[n] = true;
++pcnt[n];
return;
}
long long p = n;
while(p >= n) //值变化,防止陷入死循环k
p = Pollard_Rho(p, rand() % (n - 1) + 1);
Find_fac(n / p);
Find_fac(p);
}
int findmin() {
int minn = INF;
for(auto it : pcnt) {
minn = min(minn, it.second);
}
return minn;
}
int main() {
srand((unsigned)time(0));
int T;
cin >> T;
while(T--) {
pcnt.clear();
ll t;
cin >> t;
if (Miller_Rabin(t))
puts("1");
else {
Find_fac(t);
cout << findmin() << endl;
}
}
return 0;
}
#include
#define INF 0x3f3f3f3f
#define EXP 1e-6
#define MEM(a,x) memset(a,x,sizeof(a))
#define gcd(a,b) __gcd(a,b)
#define ll long long
#define LL long long
#define _for(i,a,b) for(int i = (a); i < (b); i++)
#define _fore(i,a,b) for(int i = (a); i <= (b); i++)
using namespace std;
bool vst[5500];
int pri[550], cnt = 0;
unordered_map<int, int> less_cnt;
ll qpow(ll a, ll b) {
ll ans = 1;
while (b) {
if (b & 1)
ans = ans * a;
b >>= 1;
a = a * a;
}
return ans;
}
double nsqrt(double x, int n) {
if (x < 0 && !(n & 1))
return -1;
double ans = pow(x, 1.0 / n);
if (abs(qpow((ll)ans + 1, n) - x) < EXP)
return ans + 1;
else
return ans;
}
void sieve(int n) { //线性筛筛出来5次根号1e18以内的素数
pri[cnt++] = 2, vst[4] = true;
for(int i = 3; i < n; i += 2) {
if(!vst[i])
pri[cnt++] = i;
for(int j = 0; (j < cnt && i * pri[j] < n); ++j) {
vst[i * pri[j]] = true;
if(i % pri[j] == 0)
break;
}
}
}
int findmin() { //找到5次根号下1e18以内,最小的质因数
int minn = INF;
for(auto it : less_cnt) {
minn = min(minn, it.second);
if (minn == 1) // 1必然是最小的,有1的话直接返回1就行了
return 1;
}
return minn;
}
int main() {
ios::sync_with_stdio(false);
sieve(3982); //3982是5次根号1e18
int T;
cin >> T;
while (T--) {
less_cnt.clear();
ll n, m, sq5 = 0;
cin >> n;
m = n, sq5 = nsqrt(n, 5);
_for(i, 0, cnt) {
if (pri[i] > sq5)
break;
while (m % pri[i] == 0) {
m /= pri[i];
++less_cnt[pri[i]]; //记录个数
}
}
if (m == 1) {
cout << findmin() << endl;
} else {
bool flag = false;
int ans = findmin();
if (ans == 1) {
cout << 1 << endl;
continue;
}
for(int i = 4; i >= 2; --i) { //必须倒着来,仔细想想4次根号和2次根号的关系就知道了
ll res = nsqrt(m, i);
if (qpow(res, i) == m) { // 这里跑了两遍快速幂其实可以优化,可我懒得改了
flag = true;
ans = min(ans, i);
break;
}
}
if(!flag) {
cout << 1 << endl;
} else {
cout << ans << endl;
}
}
}
return 0;
}