Skip to content

Commit c148591

Browse files
Merge pull request #3420 from 876pol/cses-1081
Cses 1081
2 parents c0a4cc1 + b1da88d commit c148591

File tree

1 file changed

+196
-12
lines changed

1 file changed

+196
-12
lines changed

solutions/gold/cses-1081.mdx

+196-12
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ author: Andrew Wang, Andi Qu
77

88
## Solution 1
99

10-
**Time Complexity:** $\mathcal{O}(N^2\log(\max(x_i)))$
11-
1210
The naive approach would be to brute-force each pair of numbers in the array and
1311
calculate the maximum GCD. Sadly, this solution gets TLE on around half of the
1412
test cases.
1513

14+
## Implementation
15+
16+
**Time Complexity:** $\mathcal{O}(N^2\log(\max(x_i)))$
17+
18+
<LanguageSection>
19+
<CPPSection>
20+
1621
```cpp
1722
#include <iostream>
1823
using namespace std;
@@ -45,16 +50,70 @@ int main() {
4550
}
4651
```
4752

48-
## Solution 2
53+
</CPPSection>
54+
<JavaSection>
4955

50-
**Time Complexity:** $\mathcal{O}(N\sqrt{\max(x_i)})$
56+
```java
57+
import java.io.*;
58+
import java.util.*;
59+
60+
public class CommonDivisors {
61+
public static int gcd(int a, int b) {
62+
return b == 0 ? a : gcd(b, a % b);
63+
}
64+
65+
public static void main(String[] args) throws NumberFormatException, IOException {
66+
BufferedReader io = new BufferedReader(new InputStreamReader(System.in));
67+
int n = Integer.parseInt(io.readLine());
68+
int[] arr = Arrays.stream(io.readLine().split(" "))
69+
.mapToInt(Integer::parseInt)
70+
.toArray();
71+
int ans = 1;
72+
for (int i = 0; i < n - 1; i++) {
73+
for (int j = i + 1; j < n; j++) {
74+
ans = Math.max(ans, gcd(arr[i], arr[j]));
75+
}
76+
}
77+
System.out.println(ans);
78+
}
79+
}
80+
```
81+
82+
</JavaSection>
83+
<PySection>
84+
```py
85+
from math import gcd
86+
87+
n = int(input())
88+
89+
arr = list(map(int, input().split()))
90+
91+
ans = 1
92+
for i in range(n - 1):
93+
for j in range(i + 1, n):
94+
ans = max(ans, gcd(arr[i], arr[j]))
95+
96+
print(ans)
97+
```
98+
99+
</PySection>
100+
</LanguageSection>
101+
102+
## Solution 2
51103

52104
Maintain an array, $\texttt{cnt}$, to store the count of divisors. For each
53105
value in the array, find its divisors and for each $u$ in those divisors,
54106
increment $\texttt{cnt}$ by one. The greatest GCD shared by two elements in the
55107
array will be the greatest index in our stored count for divisors with a count
56108
greater than or equal to $2$.
57109

110+
## Implementation
111+
112+
**Time Complexity:** $\mathcal{O}(N\sqrt{\max(x_i)})$
113+
114+
<LanguageSection>
115+
<CPPSection>
116+
58117
```cpp
59118
#include <cmath>
60119
#include <iostream>
@@ -97,9 +156,88 @@ int main() {
97156
}
98157
```
99158

100-
## Solution 3
159+
</CPPSection>
160+
<JavaSection>
101161

102-
**Time Complexity:** $\mathcal{O}(\max(x_i)\log(\max(x_i)))$
162+
<Warning>
163+
Due to the tight time limit, the following Java solution still receives TLE on a few of the test cases.
164+
</Warning>
165+
166+
```java
167+
import java.io.*;
168+
import java.util.*;
169+
170+
public class CommonDivisors {
171+
public static final int MAX_VAL = 1000000;
172+
173+
// divisors[i] = stores the count of numbers that have i as a divisor
174+
public static int[] divisors = new int[MAX_VAL + 1];
175+
176+
public static void main(String[] args) throws NumberFormatException, IOException {
177+
BufferedReader io = new BufferedReader(new InputStreamReader(System.in));
178+
int n = Integer.parseInt(io.readLine());
179+
int[] arr = Arrays.stream(io.readLine().split(" "))
180+
.mapToInt(Integer::parseInt)
181+
.toArray();
182+
for (int i = 0; i < n; i++) {
183+
int up = (int) Math.sqrt(arr[i]);
184+
for (int div = 1; div <= up; div++) {
185+
if (arr[i] % div == 0) {
186+
// the divisor and quotient are both divisors of a
187+
divisors[div]++;
188+
// make sure not to double count!
189+
if (div != arr[i] / div) {
190+
divisors[arr[i] / div]++;
191+
}
192+
}
193+
}
194+
}
195+
196+
for (int i = MAX_VAL; i >= 1; i--) {
197+
if (divisors[i] >= 2) {
198+
System.out.println(i);
199+
break;
200+
}
201+
}
202+
}
203+
}
204+
```
205+
206+
</JavaSection>
207+
<PySection>
208+
209+
<Warning>
210+
Due to the tight time limit, the following Python solution still receives TLE on about half the test cases.
211+
</Warning>
212+
213+
```py
214+
from math import sqrt
215+
216+
MAX_VAL = 1000000
217+
divisors = [0] * (MAX_VAL + 1)
218+
219+
n = int(input())
220+
a = list(map(int, input().split()))
221+
for i in range(n):
222+
up = int(sqrt(a[i]))
223+
for div in range(1, up + 1):
224+
if a[i] % div == 0:
225+
# the divisor and quotient are both divisors of a
226+
divisors[div] += 1
227+
# make sure not to double count!
228+
if div != a[i] // div:
229+
divisors[a[i] // div] += 1
230+
231+
for i in range(MAX_VAL, 0, -1):
232+
if divisors[i] >= 2:
233+
print(i)
234+
break
235+
```
236+
237+
</PySection>
238+
</LanguageSection>
239+
240+
## Solution 3
103241

104242
Given a value, $x$, we can check whether a pair has a GCD equal to $x$ by
105243
checking all the multiples of $x$. With that information, loop through all
@@ -110,16 +248,21 @@ $$
110248
\sum_{i = 1}^{\max(x_i)} \max(x_i)/i \approx \max(x_i)\log(\max(x_i)).
111249
$$
112250

251+
## Implementation
252+
253+
**Time Complexity:** $\mathcal{O}(\max(x_i)\log(\max(x_i)))$
254+
113255
<LanguageSection>
114256
<CPPSection>
257+
115258
```cpp
116259
#include <bits/stdc++.h>
117260
using namespace std;
118261

119262
const int MAX_VAL = 1e6;
120263

121264
// occ_num[i] contains the number of times i occurs in the array
122-
int occ_num[MAX_VAL + 1];
265+
vector<int> occ_num(MAX_VAL + 1);
123266

124267
int main() {
125268
ios_base::sync_with_stdio(0);
@@ -147,24 +290,65 @@ int main() {
147290
}
148291
}
149292
```
293+
150294
</CPPSection>
295+
<JavaSection>
296+
297+
```java
298+
import java.io.*;
299+
import java.util.*;
300+
301+
public class CommonDivisors {
302+
public static final int MAXX = 1000000;
303+
304+
public static void main(String[] args) throws NumberFormatException, IOException {
305+
BufferedReader io = new BufferedReader(new InputStreamReader(System.in));
306+
int n = Integer.parseInt(io.readLine());
307+
int[] arr = Arrays.stream(io.readLine().split(" "))
308+
.mapToInt(Integer::parseInt)
309+
.toArray();
310+
311+
int[] p = new int[MAXX + 1];
312+
Arrays.fill(p, 0);
313+
314+
for (int i = 0; i < n; i++) {
315+
p[arr[i]]++;
316+
}
317+
318+
for (int i = MAXX; i >= 1; i--) {
319+
int div = 0;
320+
for (int j = i; j <= MAXX; j += i) {
321+
div += p[j];
322+
}
323+
if (div >= 2) {
324+
System.out.println(i);
325+
break;
326+
}
327+
}
328+
}
329+
}
330+
```
331+
332+
</JavaSection>
151333
<PySection>
334+
152335
```py
153336
MAXX = int(1e6 + 5)
154337
n = int(input())
155338
arr = list(map(int, input().split()))
156-
p = [0 for i in range(MAXX)]
339+
p = [0] * MAXX
157340

158-
for i in range(n) :
341+
for i in range(n):
159342
p[arr[i]] += 1
160343

161-
for i in range(MAXX, 1, -1) :
344+
for i in range(MAXX, 0, -1):
162345
div = 0
163-
for j in range(i, MAXX, i) :
346+
for j in range(i, MAXX, i):
164347
div += p[j]
165-
if div >= 2 :
348+
if div >= 2:
166349
print(i)
167350
break
168351
```
352+
169353
</PySection>
170354
</LanguageSection>

0 commit comments

Comments
 (0)