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
| class Solution { public int minCost(int[] nums, int k) { int n = nums.length; long[] dp = new long[n + 1]; SegTree segTree = new SegTree(dp); int[] last = new int[n], last2 = new int[n]; long ans = 0; for(int i = 1; i < n + 1; i++){ int x = nums[i - 1]; segTree.update(i, i, ans, 1, n, 1); segTree.update(last[x] + 1, i, -1, 1, n, 1); if(last[x] > 0){ segTree.update(last2[x] + 1, last[x], 1, 1, n, 1); } ans = k + segTree.query(1, i, 1, n, 1); last2[x] = last[x]; last[x] = i; } return (int)ans + n; } }
class SegTree { long[] arr; int[] lazyTag;
public SegTree(long[] org) { this.arr = new long[org.length * 4]; this.lazyTag = new int[org.length * 4]; }
private void do_(int o, long v) { arr[o] += v; lazyTag[o] += v; }
private void spread(int o) { int v = lazyTag[o]; if (v != 0) { do_(o * 2, v); do_(o * 2 + 1, v); lazyTag[o] = 0; } }
public void update(int l, int r, long c, int s, int t, int p){ if (l <= s && r >= t) { do_(p, c); return; } int mid = s + (t - s >> 1); spread(p); if (l <= mid) { update(l, r, c, s, mid, p * 2); } if (r >= mid + 1) { update(l, r, c, mid + 1, t, p * 2 + 1); } arr[p] = Math.min(arr[p * 2], arr[p * 2 + 1]); }
public long query(int l, int r, int s, int t, int p){ if (l <= s && r >= t) { return arr[p]; } int mid = s + (t - s >> 1); spread(p); long min = Long.MAX_VALUE; if (l <= mid) { min = Math.min(min, query(l, r, s, mid, p * 2)); } if (r >= mid + 1) { min = Math.min(min, query(l, r, mid + 1, t, p * 2 + 1)); } return min; }
}
|