其他的几篇题解大多都是先求了
c
i
←
l
c
m
(
a
i
,
b
i
)
c_i \gets lcm(a_i,b_i)
ci←lcm(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←(ai∗bi) 最后再求所以
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})
now←gcd(ci−1,ci−2) ,然后再求
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)=p∏pmin(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)=p∏pmin(qp,cp)=p∏pmin(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;
}