Codeforces1445C.Division
Description
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\) and for each pair decided to find the greatest integer \(x_i\), such that:
- \(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 \le t \le 50)\)— the number of pairs.
Each of the following \(t\) lines contains two integers \(p_i\) and \(q_i\) \((1 \le p_i \le 10^{18})\) — 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 \(x_i\) is not divisible by .
One can show that there is always at least one value of \(x_i\) satisfying the divisibility conditions for the given constraints.
Solution
就是求p的一个最大的因数x使其不能被q整除
对于p无法被q整除的情况,直接输出p即可
现在考虑p能被q整除的情况
首先我们把p,q分解质因数
如果x不能被q整除,那x分解质因数后至少有一个质因数个数是小于q的
所以我们枚举质因数,设该质因数在q中的个数为k
则我们将p中该质因数个数除剩(k-1)个
最后答案取最大值即可
Code
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int t,i,j,tot,prime[10001],cnt[10001],cnb[10001];
bool bz[100000001];
long long a,b,ma,x,y;
int main()
{
open("1145C");
for (i=2;i<=floor(sqrt(1000000000));i++)
{
if (!bz[i])prime[++tot]=i;
for (j=1;j<=tot;j++)
{
if (prime[j]*i>floor(sqrt(1000000000))) break;
bz[prime[j]*i]=1;
if (i%prime[j]==0) break;
}
}
scanf("%d",&t);
for (;t;t--)
{
scanf("%lld%lld",&a,&b);
if (a%b)
{
printf("%lld\n",a);
continue;
}
x=a;y=b;
memset(cnt,0,sizeof(cnt));
memset(cnb,0,sizeof(cnb));
for (i=1;i<=tot;i++)
{
while (x%prime[i]==0)
{
x/=prime[i]; cnt[i]++;
}
while (y%prime[i]==0)
{
y/=prime[i];cnb[i]++;
}
}
if (y>1) cnb[tot+1]=y;
y=a;ma=0;
for (i=1;i<=tot;i++)
{
x=y;
if (!cnb[i]) continue;
for (j=1;j<=max(0,cnt[i]-cnb[i]+1);j++)
x/=prime[i];
ma=max(ma,x);
}
if (cnb[tot+1])
{
x=y;
while (x%cnb[tot+1]==0) x/=cnb[tot+1];
ma=max(ma,x);
}
printf("%lld\n",ma);
}
return 0;
}