水題挑戰6: CF1444A DIvision
A. Division
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
Oleg's favorite subjects are History and Math, and his favorite branch of mathematics is division.
To improve his division skills, Oleg came up with \(t\) pairs of integers \(p_i\) and \(q_i\)
\(p_i\) is divisible by \(x_i\);
\(x_i\) is not divisible by \(q_i\).
Oleg is really good at division and managed to find all the answers quickly, how about you?
Input
The first line contains an integer \(t\) \((1\leq t\leq 50)\)
Each of the following \(t\) lines contains two integers \(p_i\) and \(q_i\) (\(1≤p_i≤10^18\); \(2≤q_i≤10^9\)) — the \(i-th\) pair of integers.
Output
Print \(t\) integers: the \(i-th\) integer is the largest \(x_i\) such that \(p_i\) is divisible by \(x_i\), but xi is not divisible by \(q_i\)
One can show that there is always at least one value of xi satisfying the divisibility conditions for the given constraints.
Example
input
3
10 4
12 6
179 822
output
10
4
179
SOLUTION
這還算一道良心數學題
首先我們發現,我們先把p, q質因數分解,有如下結果:
\(p = a_1^p_1 \times a_2^p_2\times ... \times a_m^p_m \times ... a_n^p_n\)
\(q = a_1^q_1 \times a_2^q_2\times ... \times a_m^q_m\)
其中, \(m<n\)
注意,當\(p mod q!=0\), 答案就是\(p\)
當\(p mod q=0\)
就是任意小於\(m\)的數\(i\),\(q_i <= p_i\)
於是,我們就只要考慮前\(m\)個質因數
我們只要對於\(p\)的任意一個質因數,\(p_i\)變成\(q_i-1\),就是一個符合條件的答案
求出最大的,我們只需要考慮變化代價最小的計算出來就好了
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define _(d) while(d(isdigit(ch=getchar())))
template <class T> void g(T&t){T x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;t=f*x;}
typedef unsigned long long ll;
const int N = 1e5+4;
int pri[N], tot, vis[N];
ll p,q,ans;
void pre(){
int End = sqrt(1e9)+1;
for(int i=2; i <= End; i++){
if(!vis[i]) pri[++tot]=i;
for(int j=1; j <= tot; j++){
if( i*pri[j] > End ) break;
vis[i*pri[j]] = 1;
if( i%pri[j] == 0 ) break;
}
}
}
int st[N], tp, num1[N], num2[N];
ll s1[N], s2[N];
int main(){
int T; g(T);
pre();
// rep(i,1,10) cout<<pri[i]<<endl;
while(T--){
g(p), g(q);
if( p%q ) ans = p;
else{
tp = 0; ll nowq = q; ans = 0;
for( int i=1; pri[i]*pri[i] <= nowq && i<=tot; i++ ){
if( nowq % pri[i] == 0 ){
st[++tp] = pri[i]; s1[tp] = 1;
while( nowq % pri[i] == 0 ){
// puts("orz");
nowq /= pri[i];
s1[tp] *= pri[i];
}
}
}
if( nowq >1 ) st[++tp] = nowq, s1[tp] = nowq;
ll nowp = p;
for( int i=1; i <= tp; i++ ){
ll tmp = nowp / s1[i]; s2[i] = s1[i];
while( tmp % st[i] == 0 ){
// puts("orz");
s2[i] *= st[i];
tmp /= st[i];
}
nowp = tmp;
}
ll mn = 1e18;
for( int i=1; i <= tp; i++ ){
// cerr<<s1[i]<<endl;
s2[i] = s2[i]/s1[i]*st[i];
mn = min( mn, s2[i] );
}
ans = p/mn;
}
printf("%llu\n",ans);
}
return 0;
}