Codeforces 題解 —— Row GCD —— 數學題
技術標籤:OJ題解# CodeForces題解Codeforces題解Row GCD
題目相關
題目連結
Codeforces Round #691 (Div. 1) https://codeforces.com/problemset/problem/1458/A。
Problem Statement
You are given two positive integer sequences
a
1
,
…
,
a
n
a_1, …, a_n
a1,…,an and
b
1
,
…
,
b
m
b_1, …, b_m
b1,…,bm. For each
j
=
1
,
…
,
m
j=1, …, m
Input
The first line contains two integers
n
n
n and
m
m
m (
1
≤
n
,
m
≤
2
⋅
1
0
5
1 ≤ n, m ≤ 2⋅10^5
1≤n,m≤2⋅105).
The second line contains n integers
a
1
,
…
,
a
n
a_1, …, a_n
a1,…,an (
1
≤
a
i
≤
1
0
18
1 ≤ a_i ≤ 10^{18}
The third line contains m integers
b
1
,
…
,
b
m
b_1, …, b_m
b1,…,bm (
1
≤
b
j
≤
1
0
18
1 ≤ b_j ≤ 10^{18}
1≤bj≤1018).
Output
Print m m m integers. The j j j-th of them should be equal to G C D ( a 1 + b j , … , a n + b j ) GCD(a_1+b_j, …, a_n+b_j) GCD(a1+bj,…,an+bj).
Sample Input
4 4
1 25 121 169
1 2 7 23
Sample Output
2 3 8 24
題解報告
題目翻譯
給兩個正整數序列 a 1 , … , a n a_1, …, a_n a1,…,an 和 b 1 , … , b m b_1, …, b_m b1,…,bm,求對於每個 j = 1 , … , m j=1, …, m j=1,…,m 的 a 1 + b j , … , a n + b j a_1+b_j, …, a_n+b_j a1+bj,…,an+bj 最大公約數。
題目分析
本題是一個數學題。考點在於最大公約數的性質。
我們需要使用最大公約數的兩個性質:
1、結合律。
g
c
d
(
a
,
b
,
c
)
=
g
c
d
(
a
,
g
c
d
(
b
,
c
)
)
=
g
c
d
(
g
c
d
(
a
,
b
)
,
c
)
gcd(a,b,c)=gcd(a, gcd(b, c)) = gcd(gcd(a, b), c)
gcd(a,b,c)=gcd(a,gcd(b,c))=gcd(gcd(a,b),c)。
2、
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
b
)
=
g
c
d
(
b
,
∣
a
−
b
∣
)
=
g
c
d
(
a
,
∣
a
−
b
∣
)
gcd(a,b)=gcd(b, \frac{a}{b})=gcd(b, \lvert a-b \rvert)=gcd(a, \lvert a-b \rvert)
gcd(a,b)=gcd(b,ba)=gcd(b,∣a−b∣)=gcd(a,∣a−b∣)。
下面我們來推到一下
g
c
d
(
a
1
+
b
j
,
…
,
a
n
+
b
j
)
gcd(a_1+b_j, …, a_n+b_j)
gcd(a1+bj,…,an+bj) 如何計算,為了方便起見,我們推導
g
c
d
(
a
1
,
a
2
,
a
3
)
gcd(a_1, a_2, a_3)
gcd(a1,a2,a3)。
g
c
d
(
a
1
,
a
2
,
a
3
)
⇒
g
c
d
(
a
2
,
a
1
,
a
3
)
⇒
g
c
d
(
a
2
,
g
c
d
(
a
1
,
a
3
)
)
⇒
g
c
d
(
a
2
,
g
c
d
(
a
1
,
∣
a
1
−
a
3
∣
)
)
⇒
g
c
d
(
a
2
,
a
1
,
∣
a
1
−
a
3
∣
)
⇒
g
c
d
(
∣
a
1
−
a
3
∣
,
a
1
,
a
2
)
⇒
g
c
d
(
∣
a
1
−
a
3
∣
,
g
c
d
(
a
1
,
a
2
)
)
⇒
g
c
d
(
∣
a
1
−
a
3
∣
,
g
c
d
(
a
1
,
∣
a
1
−
a
2
∣
)
)
⇒
g
c
d
(
∣
a
1
−
a
3
∣
,
a
1
,
∣
a
1
−
a
2
∣
)
⇒
g
c
d
(
a
1
,
∣
a
1
−
a
2
∣
,
∣
a
1
−
a
3
∣
)
gcd(a_1, a_2, a_3)\Rightarrow gcd(a_2, a_1, a_3)\Rightarrow gcd(a_2, gcd(a_1, a_3)) \\ \Rightarrow gcd(a_2, gcd(a_1, \lvert a_1-a_3 \rvert))\Rightarrow gcd(a_2, a_1, \lvert a_1-a_3 \rvert)\\\Rightarrow gcd(\lvert a_1-a_3 \rvert, a_1, a_2)\Rightarrow gcd(\lvert a_1-a_3 \rvert, gcd(a_1, a_2))\\\Rightarrow gcd(\lvert a_1-a_3 \rvert,gcd(a_1,\lvert a_1-a_2 \rvert))\Rightarrow gcd(\lvert a_1-a_3 \rvert,a_1,\lvert a_1-a_2 \rvert)\\\Rightarrow gcd(a_1,\lvert a_1-a_2 \rvert, \lvert a_1-a_3 \rvert)
gcd(a1,a2,a3)⇒gcd(a2,a1,a3)⇒gcd(a2,gcd(a1,a3))⇒gcd(a2,gcd(a1,∣a1−a3∣))⇒gcd(a2,a1,∣a1−a3∣)⇒gcd(∣a1−a3∣,a1,a2)⇒gcd(∣a1−a3∣,gcd(a1,a2))⇒gcd(∣a1−a3∣,gcd(a1,∣a1−a2∣))⇒gcd(∣a1−a3∣,a1,∣a1−a2∣)⇒gcd(a1,∣a1−a2∣,∣a1−a3∣)
根據上面的過程,我們可以得到
g
c
d
(
a
1
+
b
1
,
a
2
+
b
1
,
a
3
+
b
1
,
.
.
.
,
a
n
+
b
1
)
⇒
g
c
d
(
a
1
+
b
1
,
∣
a
1
−
a
2
∣
,
∣
a
1
−
a
3
∣
,
.
.
.
,
∣
a
1
−
a
n
∣
)
⇒
g
c
d
(
a
1
+
b
1
,
g
c
d
(
∣
a
1
−
a
2
∣
,
∣
a
1
−
a
3
∣
,
.
.
.
,
∣
a
1
−
a
n
∣
)
)
gcd(a_1+b_1, a_2+b_1, a_3+b1, ..., a_n+b_1)\Rightarrow gcd(a_1+b_1, \lvert a_1-a_2 \rvert, \lvert a_1-a_3 \rvert,..., \lvert a_1-a_n \rvert)\Rightarrow gcd(a_1+b_1, gcd(\lvert a_1-a_2 \rvert, \lvert a_1-a_3 \rvert,..., \lvert a_1-a_n \rvert))
gcd(a1+b1,a2+b1,a3+b1,...,an+b1)⇒gcd(a1+b1,∣a1−a2∣,∣a1−a3∣,...,∣a1−an∣)⇒gcd(a1+b1,gcd(∣a1−a2∣,∣a1−a3∣,...,∣a1−an∣))。因為根據資料輸入,我們是先得到
a
i
a_i
ai,因此我們可以先計算
g
c
d
(
∣
a
1
−
a
2
∣
,
∣
a
1
−
a
3
∣
,
.
.
.
,
∣
a
1
−
a
n
∣
)
gcd(\lvert a_1-a_2 \rvert, \lvert a_1-a_3 \rvert,..., \lvert a_1-a_n \rvert)
gcd(∣a1−a2∣,∣a1−a3∣,...,∣a1−an∣),然後再計算最終的結果。
資料範圍分析
根據題目給出的資料,需要使用 long long。
AC 程式碼
//https://codeforces.com/contest/1458/problem/A
//A. Row GCD
#include <bits/stdc++.h>
using namespace std;
//如果提交到OJ,不要定義 __LOCAL
//#define __LOCAL
typedef long long ll;
const int MAXN=2e5+4;
ll a[MAXN], b[MAXN];
int main() {
#ifndef __LOCAL
//這部分程式碼需要提交到OJ,本地除錯不使用
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#endif
int n,m;
cin>>n>>m;
for (int i=1; i<=n; i++) {
cin>>a[i];
}
ll g=0;
for (int i=2; i<=n; i++) {
g=__gcd(g, abs(a[i]-a[i-1]));
}
for (int i=1; i<=m; i++) {
cin>>b[i];
ll ans=__gcd(a[1]+b[i], g);
cout<<ans<<" ";
}
cout<<"\n";
#ifdef __LOCAL
//這部分程式碼不需要提交到OJ,本地除錯使用
system("pause");
#endif
return 0;
}
時間複雜度
O ( m a x ( n , m ) ) O(max(n, m)) O(max(n,m))。
空間複雜度
O ( m a x ( n , m ) ) O(max(n, m)) O(max(n,m))。