1. 程式人生 > 實用技巧 >[Codeforces Round #680] C. Division

[Codeforces Round #680] C. Division

Codeforces Round #680

C. Division


首先判斷pi能否整除qi,不能這答案就是pi,否則,將\(q_i\)分解質因數,將qi的每個因子從pi中剔除成不能被\(q_i\)整除的數,pi剔除完後就是\(x_i\),且\(x_i\)不能被\(q_i\)。記錄個最大的\(x_i\)

舉例說明 \(p_i=36\)\(q_i=12\)\(p_i=2 \times2 \times3 \times3\) , \(q_i=2 \times2 \times3\),將qi的每個因子 \(2\) ,\(2\), \(3\)從pi中剔除成為不能被\(q_i\)整除,即是每個\(x_i\)

,記錄下最大的\(x_i\)

#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
typedef long long ll;
const int N=1e9;
int t,isprime[100000];
ll p,q;
vector <ll> v;
vector <pair<ll,ll> >z;
pair<ll,ll>tmp;
void sieve(){
    for(int i=0;i<=sqrt(N);i++)
        isprime[i]=true;
    isprime[0]=isprime[1]=false;
    for(int i=2;i<=sqrt(N);i++){
        if(isprime[i]){
            v.push_back(i);
            for(int j=i+i;j<=sqrt(N);j+=i){
                isprime[j]=false;
            }
        }
    }
}
int main(){
    cin>>t;
    sieve();
    while(t--){
        cin>>p>>q;
        ll go=q;
        z.clear();
        for(int i=0;i<v.size();i++){
            int ok=0;
            while(q%v[i]==0){
                ok++;
                q/=v[i];
            }
            if(ok){
                z.push_back({v[i],ok});
            }
        }  
        if(q!=1){
            z.push_back({q,1});
        }
        if(p%go!=0){
            cout<<p<<endl;
        }else{
            ll ans=0;
            for(int i=0;i<z.size();i++){
                //cout<<"z="<<z[i]<<" "<<p<<endl;
                tmp=z[i];
                ll lin=p,zz=tmp.first,cnt=tmp.second-1;
                while(lin%zz==0){
                    lin/=zz;
                }
                while(cnt--){
                    lin*=zz;
                }
                ans=max(ans,lin);
            }
            cout<<ans<<endl;
        }
    }
}