链接:https://ac.nowcoder.com/acm/contest/3007/E
来源:牛客网
题目描述
对于给定的正整数 N,求最大的正整数 A,使得存在正整数 B,满足 A3B=N
输入包含 T 组数据,1≤T≤10,000;1≤N≤1018
输入描述:
第一行数字 T 表示数据组数
接下来一行,T 个正整数 N
输出描述:
T 行,每行一个数字表示答案
输入
4 27 24 7 54
输出
3 2 1 3
官方题解如下:
考虑直接一些的做法
尝试对每个N作质因数分解,经简单的统计可得出答案,复杂度O(TN^(1/2))
我们先做简单一点的优化,容易发现其实只要枚举10^6(N^(1/3)以内)的质数就好,复杂度O(TN^(1/3)/ln(N^(1/3)))
再作进一步的分析,如果我们仅使用N^(1/4)(记为W)以内的质数去试除,那么最后余下的数X仅具有大于W的因子
此时X要么是一个完全立方数,要么对答案没有任何贡献,只需要使用二分法来验证X是不是一个完全立方数即可
复杂度O(TN^(1/4)/ln(N^(1/4))),不卡常数,真的!
其实这题主要就是优化、优化、优化
先说下思路:
比如有一个数可以拆成24*310*5
那么A就是2*3*3*3
先打素数表,太大也会超时。。
题解仅使用N^(1/4)(记为W)以内的质数去试除,并最后多判断一下
而我直接枚举10^6(N^(1/3)以内)的质数去试除,就无情TLE
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 const int INF=0x3f3f3f3f; 14 typedef long long LL; 15 const double eps =1e-8; 16 const int mod=1e9+7; 17 const int maxn=1e6+10; 18 using namespace std; 19 20 int prime[maxn], vis[maxn], pnum; 21 void mk_p(int n)//打素数表 22 { 23 pnum = 0; 24 for (int i = 2; i <= n; i++) { 25 if (!vis[i]) { 26 vis[i] = i; 27 prime[++pnum] = i; 28 } 29 for (int j = 1; j <= pnum && i * prime[j] <= n; j++) { 30 vis[i*prime[j]] = prime[j]; 31 if (i % prime[j] == 0) break; 32 } 33 } 34 } 35 36 LL solve(LL n) 37 { 38 LL ans=1; 39 for(int i=1;i<=pnum;i++) 40 { 41 int p=prime[i]; 42 int num=0; 43 if(p>n) break; 44 if(n%p==0) 45 { 46 num=0; 47 while(n%p==0) 48 { 49 num++; 50 if(num==3) 51 { 52 ans*=p; 53 num=0; 54 } 55 n/=p; 56 } 57 } 58 } 59 if(n!=1) 60 { 61 LL t=pow(n,1.0/3)+0.5; 62 if( t*t*t==n ) ans*=t; 63 } 64 return ans; 65 } 66 67 int main() 68 { 69 #ifdef DEBUG 70 freopen("sample.txt","r",stdin); 71 #endif 72 73 mk_p(40005); 74 int T; 75 scanf("%d",&T); 76 while(T--) 77 { 78 LL n; 79 scanf("%lld",&n); 80 printf("%lld ",solve(n)); 81 } 82 83 return 0; 84 }
-