Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 150 Accepted Submission(s): 28
Problem Description
You are given a positive integer n > 1. Consider all the different prime divisors of n. Each of them is included in the expansion n into prime factors in some degree. Required to find among the indicators of these powers is minimal.
Input
The first line of the input file is given a positive integer T ≤ 50000, number of positive integers n in the file. In the next T line sets these numbers themselves. It is guaranteed that each of them does not exceed 10^18.
Output
For each positive integer n from an input file output in a separate line a minimum degree of occurrence of a prime in the decomposition of n into simple factors.
Sample Input
5
2
12
108
36
65536
Sample Output
1
1
2
2
16
题意:把一个数质因数分解,然后求所有质因数的最小指数
题解:打印1-10000之间的素数表然后质因数分解,分解完剩下的那个数,最多是某个质数的4次方(因为这个质数必然大于1e4),所以讨论一下就好了,当然要注意:先看是4次方再看2次方(因为如果满足4次方一定满足2次方,但是满足4次方也满足2次方,2次方的话就不是质因数了),3次方无所谓,因为开3次方会损失精度,所以就二分一下~~最后如果2,3,4次方都不满足,那么它就是一个质数~~
别问我为什么是打印1-10000不是别的区间,1-20000就超时,不信你试试~~
上代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int MAX = 1e4+10;
ll p[MAX];
bool vis[MAX];
int cnt;
void init(){
vis[0]=vis[1]=true;
for (int i = 2; i < MAX;i++){
if(!vis[i]) p[cnt++]=i;
for (int j = 0; j < cnt&&i*p[j] < MAX;j++){
vis[i*p[j]]=true;
if(i%p[j]==0) break;
}
}
}
ll check(ll mid){
return mid*mid*mid;
}
bool solve(ll n){//判断3次方是否满足
ll l=10010,r=1000000;//因为10009是最侯一个素数,这里左区间就从10010开始,因为是3次方所以右区间是1e6
while(l<=r){
ll mid=(l+r)>>1;
ll cao=check(mid);
if(cao>n) r=mid-1;
else if(cao<n) l=mid+1;
else return true;
}
return false;
}
int main(){
init();
int t;
scanf("%d",&t);
while(t--){
ll n;
scanf("%lld",&n);
int ans=520;
for (int i = 0; i < cnt;i++){
if(n%p[i]==0){
int w=0;
while(n%p[i]==0){
n/=p[i];
w++;
}
ans=min(w,ans);
}
if(n==1) break;
}
if(n>10009){//10009是我打的表的最后一个素数
ll sq1=(ll)sqrt(n);
ll sq2=(ll)(sqrt(sqrt(n)));
if(sq2*sq2*sq2*sq2==n) ans=min(ans,4);//先判断4次方
else if(sq1*sq1==n) ans=min(ans,2);//再判断2次方
else if(solve(n)) ans=min(ans,3);//判断3次方
else ans=min(ans,1);//如果都不满足,说明是个质数
}
printf("%d\n",ans);
}
return 0;
}