[LeetCode] Maximum Valid Split Positions II

4037. Maximum Valid Split Positions II

You are given an integer array nums.

You may remove at most one element from nums. Let arr be the array of remaining elements in their original order, and let m be its length.

A split position i of arr is valid if:

  • 0 <= i < m - 1, and
  • gcd(arr[0..i]) == gcd(arr[i + 1..m - 1]).

An array of length 1 has no valid split positions.

The score of arr is the number of valid split positions in it.

Return the maximum possible score of arr.

Here, gcd(a) denotes the greatest common divisor of all elements in the array a.

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
struct Seg {
int n, log;
vector<int> lg;
vector<vector<int>> st;

Seg(vector<int>& A) {
n = A.size();
lg.resize(n + 1);
for(int i = 2; i <= n; i++) lg[i] = lg[i / 2] + 1;

log = lg[n] + 1;
st.assign(log, vector<int>(n));
st[0] = A;

for(int k = 1; k < log; k++) {
for(int i = 0; i + (1 << k) <= n; i++) {
st[k][i] = gcd(st[k - 1][i], st[k - 1][i + (1 << (k - 1))]);
}
}
}

int __query(int l, int r) {
if(l > r) return 0;
int k = lg[r - l + 1];
return gcd(st[k][l], st[k][r - (1 << k) + 1]);
}

int query(int l, int r, int skip) {
if(l > r) return 0;
if(skip < l or skip > r) return __query(l, r);
return gcd(__query(l, skip - 1), __query(skip + 1, r));
}
};

class Solution {
int n;
Seg* seg;

int getIndex(int idx, int skip) {
if(skip != -1 and idx >= skip) return idx + 1;
return idx;
}

int getScore(int skip) {
int len = n - (skip != -1);
if(len < 2) return 0;

int g = seg->query(0, n - 1, skip);

int l = 0, r = len - 2;
while(l < r) {
int m = l + (r - l) / 2;
int end = getIndex(m, skip);

if(seg->query(0, end, skip) == g) r = m;
else l = m + 1;
}

int left = l;
if(seg->query(0, getIndex(left, skip), skip) != g) return 0;

l = 0;
r = len - 2;

while(l < r) {
int m = l + (r - l + 1) / 2;
int start = getIndex(m + 1, skip);

if(seg->query(start, n - 1, skip) == g) l = m;
else r = m - 1;
}

int right = l;
if(seg->query(getIndex(right + 1, skip), n - 1, skip) != g) return 0;

return max(0, right - left + 1);
}

public:
int maxValidSplits(vector<int>& nums) {
n = nums.size();
seg = new Seg(nums);

int res = getScore(-1);
for(int skip = 0; skip < n; skip++) {
res = max(res, getScore(skip));
}
return res;
}
};
Author: Song Hayoung
Link: https://songhayoung.github.io/2026/09/03/PS/LeetCode/maximum-valid-split-positions-ii/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.