Skip to content

Commit b81db41

Browse files
authored
Improved task 3165
1 parent 8d54924 commit b81db41

File tree

1 file changed

+55
-103
lines changed
  • src/main/java/g3101_3200/s3165_maximum_sum_of_subsequence_with_non_adjacent_elements

1 file changed

+55
-103
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,77 @@
11
package g3101_3200.s3165_maximum_sum_of_subsequence_with_non_adjacent_elements;
22

33
// #Hard #Array #Dynamic_Programming #Divide_and_Conquer #Segment_Tree
4-
// #2024_06_02_Time_1927_ms_(87.75%)_Space_82.1_MB_(5.31%)
5-
6-
import java.util.stream.Stream;
4+
// #2024_11_09_Time_64_ms_(100.00%)_Space_64.1_MB_(97.01%)
75

86
public class Solution {
7+
private static final int YY = 0;
8+
private static final int YN = 1;
9+
private static final int NY = 2;
10+
private static final int NN = 3;
911
private static final int MOD = 1_000_000_007;
1012

1113
public int maximumSumSubsequence(int[] nums, int[][] queries) {
12-
int ans = 0;
13-
SegTree segTree = new SegTree(nums);
14-
for (int[] q : queries) {
15-
int idx = q[0];
16-
int val = q[1];
17-
segTree.update(idx, val);
18-
ans = (ans + segTree.getMax()) % MOD;
14+
long[][] tree = build(nums);
15+
long result = 0;
16+
for (int i = 0; i < queries.length; ++i) {
17+
result += set(tree, queries[i][0], queries[i][1]);
18+
result %= MOD;
1919
}
20-
return ans;
20+
return (int) result;
2121
}
2222

23-
static class SegTree {
24-
private static class Record {
25-
int takeFirstTakeLast;
26-
int takeFirstSkipLast;
27-
int skipFirstSkipLast;
28-
int skipFirstTakeLast;
29-
30-
public Integer getMax() {
31-
return Stream.of(
32-
this.takeFirstSkipLast,
33-
this.takeFirstTakeLast,
34-
this.skipFirstSkipLast,
35-
this.skipFirstTakeLast)
36-
.max(Integer::compare)
37-
.orElse(null);
38-
}
39-
40-
public Integer skipLast() {
41-
return Stream.of(this.takeFirstSkipLast, this.skipFirstSkipLast)
42-
.max(Integer::compare)
43-
.orElse(null);
44-
}
45-
46-
public Integer takeLast() {
47-
return Stream.of(this.skipFirstTakeLast, this.takeFirstTakeLast)
48-
.max(Integer::compare)
49-
.orElse(null);
50-
}
23+
private static long[][] build(int[] nums) {
24+
final int len = nums.length;
25+
int size = 1;
26+
while (size < len) {
27+
size <<= 1;
5128
}
52-
53-
private final Record[] seg;
54-
private final int[] nums;
55-
56-
public SegTree(int[] nums) {
57-
this.nums = nums;
58-
seg = new Record[4 * nums.length];
59-
for (int i = 0; i < 4 * nums.length; ++i) {
60-
seg[i] = new Record();
61-
}
62-
build(0, nums.length - 1, 0);
29+
long[][] tree = new long[size * 2][4];
30+
for (int i = 0; i < len; ++i) {
31+
tree[size + i][YY] = nums[i];
6332
}
64-
65-
private void build(int i, int j, int k) {
66-
if (i == j) {
67-
seg[k].takeFirstTakeLast = nums[i];
68-
return;
69-
}
70-
int mid = (i + j) >> 1;
71-
build(i, mid, 2 * k + 1);
72-
build(mid + 1, j, 2 * k + 2);
73-
merge(k);
74-
}
75-
76-
// merge [2*k+1, 2*k+2] into k
77-
private void merge(int k) {
78-
seg[k].takeFirstSkipLast =
33+
for (int i = size - 1; i > 0; --i) {
34+
tree[i][YY] =
7935
Math.max(
80-
seg[2 * k + 1].takeFirstSkipLast + seg[2 * k + 2].skipLast(),
81-
seg[2 * k + 1].takeFirstTakeLast + seg[2 * k + 2].skipFirstSkipLast);
82-
83-
seg[k].takeFirstTakeLast =
36+
tree[2 * i][YY] + tree[2 * i + 1][NY],
37+
tree[2 * i][YN] + Math.max(tree[2 * i + 1][YY], tree[2 * i + 1][NY]));
38+
tree[i][YN] =
8439
Math.max(
85-
seg[2 * k + 1].takeFirstSkipLast + seg[2 * k + 2].takeLast(),
86-
seg[2 * k + 1].takeFirstTakeLast + seg[2 * k + 2].skipFirstTakeLast);
87-
88-
seg[k].skipFirstTakeLast =
40+
tree[2 * i][YY] + tree[2 * i + 1][NN],
41+
tree[2 * i][YN] + Math.max(tree[2 * i + 1][YN], tree[2 * i + 1][NN]));
42+
tree[i][NY] =
8943
Math.max(
90-
seg[2 * k + 1].skipFirstSkipLast + seg[2 * k + 2].takeLast(),
91-
seg[2 * k + 1].skipFirstTakeLast + seg[2 * k + 2].skipFirstTakeLast);
92-
93-
seg[k].skipFirstSkipLast =
44+
tree[2 * i][NY] + tree[2 * i + 1][NY],
45+
tree[2 * i][NN] + Math.max(tree[2 * i + 1][YY], tree[2 * i + 1][NY]));
46+
tree[i][NN] =
9447
Math.max(
95-
seg[2 * k + 1].skipFirstSkipLast + seg[2 * k + 2].skipLast(),
96-
seg[2 * k + 1].skipFirstTakeLast + seg[2 * k + 2].skipFirstSkipLast);
97-
}
98-
99-
// child -> parent
100-
public void update(int idx, int val) {
101-
int i = 0;
102-
int j = nums.length - 1;
103-
int k = 0;
104-
update(idx, val, k, i, j);
105-
}
106-
107-
private void update(int idx, int val, int k, int i, int j) {
108-
if (i == j) {
109-
seg[k].takeFirstTakeLast = val;
110-
return;
111-
}
112-
int mid = (i + j) >> 1;
113-
if (idx <= mid) {
114-
update(idx, val, 2 * k + 1, i, mid);
115-
} else {
116-
update(idx, val, 2 * k + 2, mid + 1, j);
117-
}
118-
merge(k);
48+
tree[2 * i][NY] + tree[2 * i + 1][NN],
49+
tree[2 * i][NN] + Math.max(tree[2 * i + 1][YN], tree[2 * i + 1][NN]));
11950
}
51+
return tree;
52+
}
12053

121-
public int getMax() {
122-
return seg[0].getMax();
54+
private static long set(long[][] tree, int idx, int val) {
55+
int size = tree.length / 2;
56+
tree[size + idx][YY] = val;
57+
for (int i = (size + idx) / 2; i > 0; i /= 2) {
58+
tree[i][YY] =
59+
Math.max(
60+
tree[2 * i][YY] + tree[2 * i + 1][NY],
61+
tree[2 * i][YN] + Math.max(tree[2 * i + 1][YY], tree[2 * i + 1][NY]));
62+
tree[i][YN] =
63+
Math.max(
64+
tree[2 * i][YY] + tree[2 * i + 1][NN],
65+
tree[2 * i][YN] + Math.max(tree[2 * i + 1][YN], tree[2 * i + 1][NN]));
66+
tree[i][NY] =
67+
Math.max(
68+
tree[2 * i][NY] + tree[2 * i + 1][NY],
69+
tree[2 * i][NN] + Math.max(tree[2 * i + 1][YY], tree[2 * i + 1][NY]));
70+
tree[i][NN] =
71+
Math.max(
72+
tree[2 * i][NY] + tree[2 * i + 1][NN],
73+
tree[2 * i][NN] + Math.max(tree[2 * i + 1][YN], tree[2 * i + 1][NN]));
12374
}
75+
return Math.max(tree[1][YY], Math.max(tree[1][YN], Math.max(tree[1][NY], tree[1][NN])));
12476
}
12577
}

0 commit comments

Comments
 (0)