发糖啦 题解(质因子分解)

题目链接

题目思路

式子可以化简为\(x\times a^b=n(x<a)\)即可

观察这个式子其实只要\(a\)最小,那么一定满足\(b\)最大

那么我只需要枚举所有\(a\),即\(n\)的所有因子然后check即可

但是暴力\(sqrt(n)\)可能会\(TLE\),所以把他变成\(\Large p_1^{q_1}\times p_2^{q_2}...\times p_m^{q_m}\)

然后dfs求出所有因子即可

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define S s
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
char s[maxn];
int n,m,ans;
int p[40],q[40];
int prime[maxn],cnt;
bool isprime[maxn];
void getprime(int n){
    for(ll i=2;i<=n;i++){//开ll因为后面要计算i*prime[j]
        if(!isprime[i]){
            prime[++cnt]=i;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
            isprime[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
void dfs(int pos,int val){
    if(pos==m+1){
        int temp=n;
        while(temp%val==0&&val!=1){
            temp=temp/val;
        }
        if(temp<val){
            ans=min(ans,val);
        }
        return ;
    }
    for(int i=0;i<=q[pos];i++){
        dfs(pos+1,val);
        val=val*p[pos];
    }
}
signed main(){
    getprime(100000);
    int _;scanf("%d",&_);
    while(_--){
        ans=inf;
        m=0;
        scanf("%d",&n);
        int temp=n;
        for(int i=1;1ll*prime[i]*prime[i]<=temp;i++){
            if(temp%prime[i]==0){
                p[++m]=prime[i];
                int tot=0;
                while(temp%prime[i]==0){
                    temp=temp/prime[i];
                    tot++;
                }
                q[m]=tot;
            }
        }
        if(temp!=1){
            p[++m]=temp;
            q[m]=1;
        }
        dfs(1,1);
        printf("%d\n",ans);
    }
    return 0;
}

posted @ 2021-08-14 22:08  hunxuewangzi  阅读(37)  评论(0编辑  收藏  举报