CF1445C. Division 质因数分解

传送门:https://codeforces.com/contest/1445/problem/C

题意:给出两个整数p,q,要求找到最大的x使得

$p mod x =0$

$x mod q \neq 0$

题解:

要求的x实际上就是p除掉点什么东西使得x不再是q的倍数,也就x的因数中是不含有p的全部质因数了

由于$p \leq 10^{18}$,所以不能暴力分解p的质因数

所以暴力分解q的质因数,若q的质因数k的次数为$t_q$,p中k的次数为$t_p$,则x中k的次数至多为$t_q-1$,若要如此,x应为$\frac{p}{max(1,k^{t_p-t_q+1})}$

维护最大值求解即可

#include<bits/stdc++.h>
#define LL long long
using namespace std;
//LL gcd(LL a,LL b){
//    return a%b?gcd(b,a%b):b;
//}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        LL p,q;
        scanf("%lld %lld",&p,&q);
        LL t=p;
        LL qt=q;
        LL pt=p;
        //map<LL,LL> qdiv,pdiv;
        //vector<LL> ans;
        //ans.clear();
        LL qdiv,pdiv;
        LL ans;
        ans=0x3f3f3f3f3f3f3f3f;
        //qdiv.clear();pdiv.clear();
        for(LL i=2;i*i<=qt;i++){
            if(qt%i==0){
                qdiv=1;
                while(qt%i==0){
                    qt/=i;
                    qdiv*=i;
                }
                pdiv=1;
                while(pt%i==0){
                    pt/=i;
                    pdiv*=i;
                }
                ans=min(ans,max(1ll,    pdiv/(qdiv/i)   ) );
                //printf("debug %lld\n",ans);
                //qdiv.push_back(i);
            }
        }
        LL i=qt;
        if(i>1){
                qdiv=1;
                while(qt%i==0){
                    qt/=i;
                    qdiv*=i;
                }
                pdiv=1;
                while(pt%i==0){
                    pt/=i;
                    pdiv*=i;
                }
                ans=min(ans,max(1ll,    pdiv/(qdiv/i)   ) );
                //printf("debug %lld\n",ans);
                //qdiv.push_back(i);
            }
        //if(qt>1)qdiv[qt]=qt;
//        while(t%q==0){
//            while(t%*it!=0)it++;
//            t/=*it;
//        }
printf("%lld\n",p/ans);
//        if(p%q!=0){
//            printf("%lld\n",p);
//        }else{
//            LL ans=p;
//            while(ans%q==0){
//                ans=gcd(ans/q,q)*(ans/q);
//            }
//            printf("%lld\n",ans);
//            
//        }
//        LL ans=p;
//        for(map<LL,LL>::iterator it=qdiv.begin();it!=qdiv.end();it++){
//            ans=min(ans,it->second);
//        }
        
    }
    return 0;
}

 

posted @ 2020-11-12 15:39  Isakovsky  阅读(160)  评论(0编辑  收藏  举报