Codeforces Round #641 (Div. 2) C. Orac and LCM

https://codeforces.com/contest/1350/problem/C

C. Orac and LCM

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

For the multiset of positive integers s={s1,s2,…,sk}s={s1,s2,…,sk}, define the Greatest Common Divisor (GCD) and Least Common Multiple (LCM) of ss as follow:

  • gcd(s)gcd(s) is the maximum positive integer xx, such that all integers in ss are divisible on xx.
  • lcm(s)lcm(s) is the minimum positive integer xx, that divisible on all integers from ss.

For example, gcd({8,12})=4,gcd({12,18,6})=6gcd({8,12})=4,gcd({12,18,6})=6 and lcm({4,6})=12lcm({4,6})=12. Note that for any positive integer xx, gcd({x})=lcm({x})=xgcd({x})=lcm({x})=x.

Orac has a sequence aa with length nn. He come up with the multiset t={lcm({ai,aj}) | i<j}t={lcm({ai,aj}) | i<j}, and asked you to find the value of gcd(t)gcd(t) for him. In other words, you need to calculate the GCD of LCMs of all pairs of elements in the given sequence.

Input

The first line contains one integer n (2≤n≤100000)n (2≤n≤100000).

The second line contains nn integers, a1,a2,…,ana1,a2,…,an (1≤ai≤2000001≤ai≤200000).

Output

Print one integer: gcd({lcm({ai,aj}) | i<j})gcd({lcm({ai,aj}) | i<j}).

Examples

input

Copy

2
1 1

output

Copy

1

input

Copy

4
10 24 40 80

output

Copy

40

input

Copy

10
540 648 810 648 720 540 594 864 972 648

output

Copy

54

Note

For the first example, t={lcm({1,1})}={1}t={lcm({1,1})}={1}, so gcd(t)=1gcd(t)=1.

For the second example, t={120,40,80,120,240,80}t={120,40,80,120,240,80}, and it's not hard to see that gcd(t)=40gcd(t)=40.

 题意:先求所有数字中任意两数字的LCM,再求所有LCM的GCD.

思路:首先要了解lcm和gcd的本质:

根据算术基本定理:

a= \prod_{prime[i]}^{n}prime[i]^{cnt[i]}                        b= \prod_{prime[j]}^{n}prime[j]^{cnt[j]}

LCM(a,b)= \prod_{prime[k]}^{n}prime[k]^{max(cnt[i],cnt[j])}              GCD(a,b)= \prod_{prime[k]}^{n}prime[k]^{min(cnt[i],cnt[j])}

例:4=2^2*3^0         6=2^1*3^1

LCM(a,b)=2^2*3=12

GCD(a,b)=2^1*3^0=2

因此,在任意两数LCM时,求的就是两数公共素数因子的次方较大值,而再求gcd就是求所有较大值中的最小值,记录每个素数的次方值并排序,如果n个数都有此素因子,则求完任意两个较大值后求出的较小值就是所有次方值的第二小值,如果n-1个数有此素因子,则是所有次方值的第二小值,其他情况则有只是两个0,求较大值后为0,再求较小值还为0,即不在结果中。

例:

4

10 24 40 80

2*5   2^3*3   2^3*5   2^4*5

2 : 1 3 3 4   LCM:3 3 4 3 4 4 (任意两者较大值)LCM的GCD:3(LCM所有值中的最小值)

3 :0 1 0 0  LCM:1 0 0 1 1 0     LCM的GCD:0

5:1 0 1 1   LCM:   1 1 1 1 1 1    LCM的GCD:1

则答案为:2^3 * 5 = 40

#include<iostream>
#include<algorithm>
#define ll long long
#include<vector>
 
using namespace std;

const int N = 100000 + 10;
const int M = 200000 + 10;

ll prime[M];
ll num[N];
vector<ll> v[M];
ll vis[M];
ll cnt;

ll ksm(ll a, ll b)
{
	ll rul = 1;
	while(b)
	{
		if(b & 1) rul = rul * a;
		b >>= 1;
		a *= a;
	}
	return rul;
}

void getprime()
{
	for(ll i=2; i<M; i++)
	{
		if(!vis[i])
		{
			prime[cnt++] = i;
			for(ll j=i+i; j<M; j+=i)
			{
				vis[j] = 1;
			}
		}
	}
}

int main()
{
	getprime();
	ll n;
	cin>>n;
	for(ll i=1; i<=n; i++)
	{
		scanf("%lld",&num[i]);
		for(ll j=0; j<cnt&&num[i]>=prime[j]*prime[j]; j++)//注意剪枝,否则TL
		{			
			if(num[i] % prime[j] == 0)
			{
				ll tem = 0;
				while(num[i] % prime[j] == 0)
				{
					num[i] /= prime[j];
					tem++;
				}					
				v[prime[j]].push_back(tem);
			}
		}
		if(num[i] > 1) v[num[i]].push_back(1);
	}
	for(ll i=0; i<cnt; i++)
	{
		sort(v[prime[i]].begin(), v[prime[i]].end());
	}
	ll ans = 1;
	for(ll i=0; i<cnt; i++)
	{
		if(v[prime[i]].size() == n) ans *= ksm(prime[i], v[prime[i]][1]);
		else if(v[prime[i]].size() == n-1) ans *= ksm(prime[i], v[prime[i]][0]);
	}
	cout<<ans;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值