B.Basic Gcd Problem(质因数分解)

B.Basic Gcd Problem(质因数分解)

思路:考虑 c c 的贡献次数,我们最后的答案肯定是: c c n t c^{cnt} 形式,所以我们只需求出 c n t cnt

e p : n = 16 , c = 5 ep:n=16,c=5

显然 f c ( 16 ) = c × m a x { f c ( i ) } , i { 1 , 2 , 4 , 8 } f_c(16)=c\times max\{f_c(i)\},i\in\{1,2,4,8\}

f c ( 1 ) = 1 f_c(1)=1

f c ( 2 ) = c × m a x { f c ( i ) } , i { 1 } f c ( 2 ) = c f_c(2)=c\times max\{f_c(i)\},i\in\{1\}\rightarrow f_c(2)=c

f c ( 4 ) = c × m a x { f c ( i ) } , i { 1 , 2 } f c ( 4 ) = c 2 f_c(4)=c\times max\{f_c(i)\},i\in\{1,2\}\rightarrow f_c(4)=c^2

f c ( 8 ) = c × m a x { f c ( i ) } , i { 1 , 2 , 4 } f c ( 8 ) = c 3 f_c(8)=c\times max\{f_c(i)\},i\in\{1,2,4\}\rightarrow f_c(8)=c^3

所以 f c ( 16 ) = c 4 , c n t = 4 f_c(16)=c^4,cnt=4

看了上面这个样例你可能已经发现了 c n t cnt 跟因数有关系。

因为我们要让 c n t cnt 尽可能大,所以我们需要尽可能多的进行相乘转换。

我们换个方式考虑: n = 16 = 2 4 n=16=2^4

1 × 2 = 2 , 2 × 2 = 4 , 4 × 2 = 8 , 8 × 2 = 16 1\times2=2,2\times2=4,4\times2=8,8\times2=16

这样是不是很显然了。

再来: e p : n = 60 = 2 2 × 3 × 5 ep:n=60=2^2\times3\times 5

1 × 2 = 2 2 × 2 = 4 , 4 × 3 = 12 , 12 × 5 = 60 1\times 2=2,2\times2=4,4\times3=12,12\times5=60

显然按照质因数分解后的个数依次相乘 c n t cnt 是最大的。

即答案就是质因数个数之和。

接下来就很简单了,可以考虑直接暴力 O ( n ) O(\sqrt{n}) 一边分解一边计算贡献,或者预处理一波每个数的对应素数。 O ( l o g n ) O(logn)

总复杂度: O ( T n ) O(T\sqrt{n}) O ( n l o g l o g n + T l o g n ) O(nloglogn+Tlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,c;
        scanf("%d%d",&n,&c);
        ll ans=1;
        for(int i=2;i*i<=n;i++){
             while(n%i==0){
                 n/=i;
                 ans=ans*c%mod;
             }
        }
        if(n!=1) ans=ans*c%mod;
        printf("%lld\n",ans);
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
bool a[N];
int b[N],p[N];
void Ess(){
     int cnt=0;
     int n=1e6;
     a[1]=true;
     for(int i=2;i<=n;i++)
     {
        if(!a[i]) p[cnt++]=i,b[i]=i;
        for(int j=0;j<cnt&&i*p[j]<=n;j++)
        {
            a[i*p[j]]=true,b[i*p[j]]=p[j];
            if(i%p[j]==0) break;
        }
     }
}
ll ksm(ll a,ll n){
    ll ans=1;
    while(n){
        if(n&1) ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans;
}
int main(){
    int t;
    Ess();
    scanf("%d",&t);
    while(t--){
        ll n,c;
        scanf("%lld%lld",&n,&c);
        if(!a[n]) printf("%lld\n",c%mod);
        else {
            int cnt=0;
            while(n!=1){
                n/=b[n];
                cnt++;
            }
            printf("%lld\n",ksm(c,cnt));
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107469645