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
",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
",ma);
    }
    return 0;
}
如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.
原文地址:https://www.cnblogs.com/Sport-river/p/13916889.html