2020牛客寒假算法基础集训营6 E-立方数 (线性筛)

思路很巧妙很有学习意义的一道题,首先我们可以知道把这个数字分解质因数,那么同一个质因数出现三次就可以把它乘进ans里,问题复杂度就是O(T*n^(1/3)/ln(n^(1/3)))(估算的质数密度),肯定超时了,那么问题就是怎么优化,注意到当你把n^(1/4)以下的因子都筛出来了之后,剩下的数字只含有大于n^(1/4)的因子了,而这样的因子最多只能有三个,所以只要判断是不是完全立方数就行。

最后还要注意一个问题,如果要用cbrt判断,需要把long long转化为long double,否则就默认double,就溢出了,或者用cbrtl,默认是long double

#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const ll N = 5 * 1e4 + 10;
const long double EPS = 1e-8;
bool f[N];
ll p[N];
int main() {
    int c = 0;
    for (int i = 2; i <= N; i++) {
        if (!f[i])    p[c++] = i;
        for (int j = 0; j < c && p[j] * i <= N; j++) {
            f[p[j] * i] = true;
            if (i % p[j] == 0)
                break;
        }
    }
    int t;
    scanf("%d", &t);
    while (t--) {
        ll n, ans = 1;
        scanf("%lld", &n);
        for (int i = 0; i < c; i++) {
            if (n == 1)
                break;
            if (n % p[i] == 0) {
                int cnt = 0;
                while (n % p[i] == 0) {
                    n = n / p[i];
                    cnt++;
                    if (cnt == 3) {
                        ans = ans * p[i];
                        cnt = 0;
                    }
                }
            }
        }
        long long a = cbrtl(n);
        if (a * a * a == n)
            ans = ans * a;
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/cminus/p/12409880.html