CF1025B 题解

其他的几篇题解大多都是先求了 c i ← l c m ( a i , b i ) c_i \gets lcm(a_i,b_i) cilcm(ai,bi) ,然后求全部 c i c_i ci 的最大公约数,但是对每一组数都求一下 l c m ( a i , b i ) lcm(a_i,b_i) lcm(ai,bi) 会增加时间复杂度,所以直接把 a i a_i ai b i b_i bi 乘起来就行,不妨记录 c i ← ( a i ∗ b i ) c_i \gets (a_i * b_i) ci(aibi) 最后再求所以 c i c_i ci 的最大公约数,求所以 c i c_i ci 的最大公约数的方法是先求 n o w ← g c d ( c i − 1 , c i − 2 ) now \gets gcd(c_{i-1},c_{i-2}) nowgcd(ci1,ci2) ,然后再求 g c d ( n o w , c i ) gcd(now,c_i) gcd(now,ci) ,为什么 g c d ( a , b , c ) = g c d ( g c d ( a , b ) , c ) gcd(a,b,c)=gcd(gcd(a,b),c) gcd(a,b,c)=gcd(gcd(a,b),c) 呢,因为
g c d ( a , b ) = ∏ p p m i n ( a p , b p ) gcd(a,b)=\prod_{p} p^{min(a_p,b_p)} gcd(a,b)=ppmin(ap,bp)

其中 a p a_p ap b p b_p bp a , b a,b a,b 质因数 p p p 的指数,记上面这个大式子为 q q q ,那么
g c d ( q , b ) = ∏ p p m i n ( q p , c p ) = ∏ p p m i n ( m i n ( a p , b p ) , c p ) gcd(q,b)=\prod_{p} p^{min(q_p,c_p)}=\prod_{p} p^{min(min(a_p,b_p),c_p)} gcd(q,b)=ppmin(qp,cp)=ppmin(min(ap,bp),cp)
因为 m i n ( m i n ( a , b ) , c ) min(min(a,b),c) min(min(a,b),c) 等价于 m i n ( a , b , c ) min(a,b,c) min(a,b,c) ,即 m i n min min 满足结合律 ,所以 g c d gcd gcd 也是满足结合律的。

当然求出所以 c i c_i ci 的最大公约数(记作 a n s ans ans )是不满足要求的 ,但是因为 a n s ans ans 的质因数一定在所以 c i c_i ci 中都有,所以 a n s ans ans 的质因数一定是在与 c i c_i ci 对应的 a i a_i ai b i b_i bi 至少一个中存在 ,且指数小于等于 m i n ( a p , b p ) min(a_p,b_p) min(ap,bp) ,所以输出 a n s ans ans 输出一个质因数即可,显然当所有 c i c_i ci 的最大公约数为 1 1 1 时不存在 ,但是这题有点卡质因数分解 ,所以判断一下选 a 1 a_1 a1 还是 b 1 b_1 b1 然后与 a n s ans ans 取个最大公约数能减小要分解的数的大小 ,具体见代码实现

代码实现:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll read()
{
	ll X=0,w=0;char ch=0;
	while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
	while(isdigit(ch)){X=(X<<3)+(X<<1)+(ch^48);ch=getchar();}
	return w?-X:X;
}

void write(ll x)
{
	if(x<0){putchar('-');x=-x;}
	if(x>9){write(x/10);}
	putchar(x%10+'0');
}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
struct node
{
	ll a,b,l;
	
};
ll f(ll x)
{
	for(int i=2;i<=sqrt(x);i++)
	{
		if(x%i==0){
			return i;
		}
	}
	return x;
}
int main()
{
	ll n=read();
	node arr[150000];
	ll aaa,bbb;
	cin>>aaa>>bbb;
	 for(int i=1;i<n;i++)
	 {
	 	arr[i].a=read();
	 	arr[i].b=read();
	 	arr[i].l=arr[i].a*arr[i].b;
        aaa=gcd(arr[i].a*arr[i].b,aaa);
        bbb=gcd(arr[i].a*arr[i].b,bbb);
	 }
	 ll now=gcd(arr[0].l,arr[1].l);
	for (int i=2;i<n;i++)
	{
		now=gcd(now,arr[i].l);
	}
	if(now==1)
	{
		cout<<"-1";
		return 0;
	}
	if(aaa!=1)
	{
		cout<<f(aaa);
	}
	else if(bbb!=1) cout<<f(bbb);
	else cout<<"-1";
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值