2020牛客寒假算法基礎集訓營6 E-立方數 - 質因子分解

題目鏈接:https://ac.nowcoder.com/acm/contest/3007/E
題目大意:
在這裏插入圖片描述
在這裏插入圖片描述
我們要求最大的A。
我們根據唯一分解定理:
N=e1p1e2p2e2p2e2p2...ekpkN=e_1^{p_1}*e_2^{p_2}*e_2^{p_2}*e_2^{p_2}*...e_k^{p_k}
那麼
pi%3==0A=ei(pi/3)如果pi\%3==0那麼A*=e_i*(pi/3)
現在我們就是要eiA枚舉ei來得到A
我們發現eiN1/3e_i的最大值爲N^{1/3}
我們枚舉N1/3O(TN(1/3)/ln(N(1/3)))N^{1/3}裏的素數那麼複雜度是O(TN^{(1/3)}/ln(N^{(1/3)}))
我們可以進一步優化:N1/4,NN1/4X如果枚舉到N^{1/4},那麼我們把N在N^{1/4}裏的素數全部篩出後得到X
XepB,e,B>N1/4p<4p>=4epB>N那麼X的形式爲e^{p}*B,並且e, B>N^{1/4},那麼可以知道:p<4。如果p>=4那麼e^{p}*B>N
1:p=3B1N3/4B,B>N1/4N3/4B>N,B=12:p<3ei \begin{array}{l} 1:p=3那麼B一定等於1 證明N^{3/4}*B,而且B>N^{1/4}那麼N^{3/4}*B>N不可能,所以B=1 \\ \\ 2:p<3那麼ei對結果沒有貢獻 \\ \end{array}
N1/4,X:O(TN(1/4)/ln(N(1/4)))所以我們枚舉N^{1/4}的素數,再判斷X是否爲立方數,複雜度:O(TN^{(1/4)}/ln(N^{(1/4)}))

#include<bits/stdc++.h>
#define LL long long
using namespace std;
 
#define MAXN 1000005
#define MAXL 5299710
LL prime[MAXN];
LL Lf[MAXN];//存儲立方
LL check[MAXL];
LL tot = 0;
void get_prime(LL n){
    memset(check, 0, sizeof(check));
    for(LL i = 2; i <= n; ++i){
      if (!check[i])
        prime[tot++] = i, Lf[tot-1]=i*i*i;
 
      for (LL j = 0; j < tot; ++j){
        if (i * prime[j] > n)
          break;
 
        check[i*prime[j]] = 1;
        if (i % prime[j] == 0)
          break;
      }
    }
}
 
int main(){
 
    get_prime(31622);
    int t;scanf("%d", &t);
    while(t--){
        LL n, A=1;scanf("%lld", &n);
        for(int i=0; i<tot&&prime[i]<=n; i++){
            while(n%Lf[i]==0){//立方篩完
                A*=prime[i];
                n/=Lf[i];
            }
            while(n%prime[i]==0){
                n/=prime[i];
            }
        }
 
        int lb = 1, rb = 1000000;//二分判斷X是不是立方數
        while(lb <= rb){
            int md = lb + rb >> 1;
            if((LL)md * md * md < n)
                lb = md + 1;
            else
                rb = md - 1;
        }
        if((LL)lb * lb * lb == n)
            A *= lb;
        printf("%lld\n", A);
    }
 
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章