[题解]CF1350C-Orac and LCM

题目大意

​ 给定集合\(\{a_1,a_2,...,a_n\}\),求\(gcd(\{lcm(\{a_i,a_j\})|i<j\})\)

​ $2 n 1e5 $ , \(1 \leq a_i \leq 2e5\)

思路

​ 考虑唯一分解定理:

\(a = \prod^{n}_{1}p_i^{k_i}\)

\(b = \prod^{n}_{1}p_i^{g_i}\)

​ 对于 \(gcd\)\(lcm\) ,我们有:

\(gcd(a,b) = \prod^{n}_{1}p_i^{min(k_i,g_i)}\)

\(lcm(a,b) = \prod^{n}_{1}p_i^{max(k_i,g_i)}\)

​ 观察易得,对于答案中的每个质因子\(p_i\),它的指数\(k_i\)\(\{a_1,...,a_n\}\)\(p_i\) 第二小 的指数\(k\)

​ 我们预处理出\(i\)的所有质因数\(p[i]\),将\(a_i\)分解,用\(d[i][j]\)表示\(a_j\)的质因子\(i\)的指数,排序后扫一遍\(d[i]\)即可得到答案

​ 具体来说 \[ ans *= \left\{ \begin{array}{lcl} i^{d[i][0]}&& {d[i].size() == n-1} \\ i^{d[i][1]} && {d[i].size() \geq n-1 }\\ 1 && otherwise \end{array} \right. \]

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//C
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e6+10;
int raw[maxn];
int vis[maxn];
ll Pow(int x,int d){
ll tans = 1;
if(d == 0)return 1;
ll a = Pow(x,d/2);
tans = a*a;
if(d%2)tans = tans*x;
return tans;
}
bool n_prime[maxn];
vector<int>p[maxn],d[maxn];
void prime(){
for(int i = 2;i <maxn;i++){
if(!n_prime[i]){
p[i].push_back(i);
for(int j = i*2;j < maxn;j += i){
n_prime[j] = 1;
p[j].push_back(i);
}
}
}
n_prime[1] = 1;
}
int main(){
prime();
int n;
cin >> n;
for(int i = 1;i <= n;i++)cin >> raw[i];
for(int i = 1;i <= n;i++){
int u = raw[i];
for(int x:p[u]){
int yay = 0;
while(u%x == 0){
yay++;
u /= x;
}
d[x].push_back(yay);
}
}
ll ans = 1;
for(int i = 2;i < maxn;i++){
sort(d[i].begin(),d[i].end());
if(d[i].size() == n-1){
ans *= Pow(i,d[i][0]);
}
else if(d[i].size() > n-1)ans *= Pow(i,d[i][1]);
}
cout << ans;
return 0;
}