|  | 
| 1 | 1 | package g3401_3500.s3414_maximum_score_of_non_overlapping_intervals; | 
| 2 | 2 | 
 | 
| 3 | 3 | // #Hard #Array #Dynamic_Programming #Sorting #Binary_Search | 
| 4 |  | -// #2025_01_07_Time_63_(94.92%)_Space_88.95_(71.19%) | 
|  | 4 | +// #2025_01_08_Time_64_(95.65%)_Space_74.80_(98.26%) | 
| 5 | 5 | 
 | 
| 6 | 6 | import java.util.Arrays; | 
| 7 |  | -import java.util.Comparator; | 
| 8 | 7 | import java.util.List; | 
| 9 | 8 | 
 | 
| 10 |  | -@SuppressWarnings("java:S6541") | 
| 11 | 9 | public class Solution { | 
| 12 | 10 |     public int[] maximumWeight(List<List<Integer>> intervals) { | 
| 13 |  | -        int n = intervals.size(); | 
| 14 |  | -        int[][] arr = new int[n][4]; | 
| 15 |  | -        for (int i = 0; i < n; i++) { | 
| 16 |  | -            arr[i][0] = intervals.get(i).get(0); | 
| 17 |  | -            arr[i][1] = intervals.get(i).get(1); | 
| 18 |  | -            arr[i][2] = intervals.get(i).get(2); | 
| 19 |  | -            arr[i][3] = i; | 
|  | 11 | +        final int n = intervals.size(); | 
|  | 12 | +        final int[][] ns = new int[n][]; | 
|  | 13 | +        int p = 0; | 
|  | 14 | +        for (List<Integer> li : intervals) { | 
|  | 15 | +            ns[p] = new int[] {li.get(0), li.get(1), li.get(2), p}; | 
|  | 16 | +            p++; | 
| 20 | 17 |         } | 
| 21 |  | -        Arrays.sort(arr, (a, b) -> Long.compare(a[1], b[1])); | 
| 22 |  | -        int[] p = new int[n]; | 
| 23 |  | -        for (int i = 0; i < n; i++) { | 
| 24 |  | -            int l = 0; | 
| 25 |  | -            int r = i - 1; | 
| 26 |  | -            while (l <= r) { | 
| 27 |  | -                int m = (l + r) >>> 1; | 
| 28 |  | -                if (arr[m][1] < arr[i][0]) { | 
| 29 |  | -                    l = m + 1; | 
|  | 18 | +        int[][] dp1 = new int[n][0]; | 
|  | 19 | +        long[] dp = new long[n]; | 
|  | 20 | +        Arrays.sort(ns, (a, b) -> (a[0] - b[0])); | 
|  | 21 | +        for (int k = 0; k < 4; ++k) { | 
|  | 22 | +            int[][] dp3 = new int[n][]; | 
|  | 23 | +            long[] dp2 = new long[n]; | 
|  | 24 | +            dp3[n - 1] = new int[] {ns[n - 1][3]}; | 
|  | 25 | +            dp2[n - 1] = ns[n - 1][2]; | 
|  | 26 | +            for (int i = n - 2; i >= 0; --i) { | 
|  | 27 | +                int l = i + 1, r = n - 1; | 
|  | 28 | +                while (l <= r) { | 
|  | 29 | +                    final int mid = (l + r) >> 1; | 
|  | 30 | +                    if (ns[mid][0] > ns[i][1]) { | 
|  | 31 | +                        r = mid - 1; | 
|  | 32 | +                    } else { | 
|  | 33 | +                        l = mid + 1; | 
|  | 34 | +                    } | 
|  | 35 | +                } | 
|  | 36 | +                dp2[i] = ns[i][2] + (l < n ? dp[l] : 0); | 
|  | 37 | +                if (i + 1 < n && dp2[i + 1] > dp2[i]) { | 
|  | 38 | +                    dp2[i] = dp2[i + 1]; | 
|  | 39 | +                    dp3[i] = dp3[i + 1]; | 
| 30 | 40 |                 } else { | 
| 31 |  | -                    r = m - 1; | 
|  | 41 | +                    if (l < n) { | 
|  | 42 | +                        dp3[i] = new int[dp1[l].length + 1]; | 
|  | 43 | +                        dp3[i][0] = ns[i][3]; | 
|  | 44 | +                        for (int j = 0; j < dp1[l].length; ++j) { | 
|  | 45 | +                            dp3[i][j + 1] = dp1[l][j]; | 
|  | 46 | +                        } | 
|  | 47 | +                        Arrays.sort(dp3[i]); | 
|  | 48 | +                    } else { | 
|  | 49 | +                        dp3[i] = new int[] {ns[i][3]}; | 
|  | 50 | +                    } | 
|  | 51 | +                    if (i + 1 < n && dp2[i + 1] == dp2[i] && check(dp3[i], dp3[i + 1]) > 0) { | 
|  | 52 | +                        dp3[i] = dp3[i + 1]; | 
|  | 53 | +                    } | 
| 32 | 54 |                 } | 
| 33 | 55 |             } | 
| 34 |  | -            p[i] = r; | 
|  | 56 | +            dp = dp2; | 
|  | 57 | +            dp1 = dp3; | 
| 35 | 58 |         } | 
|  | 59 | +        return dp1[0]; | 
|  | 60 | +    } | 
| 36 | 61 | 
 | 
| 37 |  | -        class S { | 
| 38 |  | -            long sum; | 
| 39 |  | -            int[] x; | 
| 40 |  | - | 
| 41 |  | -            S(long s, int[] t) { | 
| 42 |  | -                sum = s; | 
| 43 |  | -                x = t; | 
|  | 62 | +    private int check(final int[] ns1, final int[] ns2) { | 
|  | 63 | +        int i = 0; | 
|  | 64 | +        while (i < ns1.length && i < ns2.length) { | 
|  | 65 | +            if (ns1[i] < ns2[i]) { | 
|  | 66 | +                return -1; | 
|  | 67 | +            } else if (ns1[i] > ns2[i]) { | 
|  | 68 | +                return 1; | 
| 44 | 69 |             } | 
|  | 70 | +            i++; | 
| 45 | 71 |         } | 
| 46 |  | - | 
| 47 |  | -        S base = new S(0, new int[0]); | 
| 48 |  | -        S[][] dp = new S[n][5]; | 
| 49 |  | -        Comparator<S> cmp = | 
| 50 |  | -                (a, b) -> { | 
| 51 |  | -                    if (a.sum != b.sum) { | 
| 52 |  | -                        return a.sum > b.sum ? -1 : 1; | 
| 53 |  | -                    } | 
| 54 |  | -                    for (int i = 0; i < Math.min(a.x.length, b.x.length); i++) { | 
| 55 |  | -                        if (a.x[i] != b.x[i]) { | 
| 56 |  | -                            return a.x[i] < b.x[i] ? -1 : 1; | 
| 57 |  | -                        } | 
| 58 |  | -                    } | 
| 59 |  | -                    return Integer.compare(a.x.length, b.x.length); | 
| 60 |  | -                }; | 
| 61 |  | -        for (int i = 0; i < n; i++) { | 
| 62 |  | -            dp[i][0] = base; | 
| 63 |  | -            for (int k = 1; k <= 4; k++) { | 
| 64 |  | -                S no = (i > 0) ? dp[i - 1][k] : base; | 
| 65 |  | -                long pickVal = arr[i][2] + ((p[i] >= 0) ? dp[p[i]][k - 1].sum : 0); | 
| 66 |  | -                int[] pickPath; | 
| 67 |  | -                if (p[i] >= 0) { | 
| 68 |  | -                    pickPath = merge(dp[p[i]][k - 1].x, arr[i][3]); | 
| 69 |  | -                } else { | 
| 70 |  | -                    pickPath = new int[] {arr[i][3]}; | 
| 71 |  | -                } | 
| 72 |  | -                S pick = new S(pickVal, pickPath); | 
| 73 |  | -                dp[i][k] = (cmp.compare(no, pick) <= 0) ? no : pick; | 
| 74 |  | -            } | 
|  | 72 | +        if (i < ns1.length) { | 
|  | 73 | +            return 1; | 
| 75 | 74 |         } | 
| 76 |  | -        S ans = base; | 
| 77 |  | -        for (int k = 1; k <= 4; k++) { | 
| 78 |  | -            S candidate = dp[n - 1][k]; | 
| 79 |  | -            if (ans.sum < candidate.sum | 
| 80 |  | -                    || ans.sum == candidate.sum && cmp.compare(ans, candidate) > 0) { | 
| 81 |  | -                ans = candidate; | 
| 82 |  | -            } | 
|  | 75 | +        if (i < ns2.length) { | 
|  | 76 | +            return -1; | 
| 83 | 77 |         } | 
| 84 |  | -        Arrays.sort(ans.x); | 
| 85 |  | -        return ans.x; | 
| 86 |  | -    } | 
| 87 |  | - | 
| 88 |  | -    private int[] merge(int[] a, int v) { | 
| 89 |  | -        int[] r = new int[a.length + 1]; | 
| 90 |  | -        System.arraycopy(a, 0, r, 0, a.length); | 
| 91 |  | -        r[a.length] = v; | 
| 92 |  | -        return r; | 
|  | 78 | +        return 0; | 
| 93 | 79 |     } | 
| 94 | 80 | } | 
0 commit comments