Skip to content

Commit 49f6123

Browse files
2818_Apply_Operations_to_Maximize_Score.java
1 parent b874ccb commit 49f6123

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Problem Number: 2818
2+
3+
// Apply Operations to Maximize Score.
4+
5+
class Solution {
6+
public int maximumScore(List<Integer> nums, int k) {
7+
final int n = nums.size();
8+
final int mx = Collections.max(nums);
9+
final int[] minPrimeFactors = sieveEratosthenes(mx + 1);
10+
final int[] primeScores = getPrimeScores(nums, minPrimeFactors);
11+
int ans = 1;
12+
13+
int[] left = new int[n];
14+
Arrays.fill(left, -1);
15+
int[] right = new int[n];
16+
Arrays.fill(right, n);
17+
Deque<Integer> stack = new ArrayDeque<>();
18+
19+
for (int i = n - 1; i >= 0; --i) {
20+
while (!stack.isEmpty() && primeScores[stack.peek()] <= primeScores[i])
21+
left[stack.pop()] = i;
22+
stack.push(i);
23+
}
24+
25+
stack.clear();
26+
for (int i = 0; i < n; ++i) {
27+
while (!stack.isEmpty() && primeScores[stack.peek()] < primeScores[i])
28+
right[stack.pop()] = i;
29+
stack.push(i);
30+
}
31+
32+
Pair<Integer, Integer>[] numAndIndexes = new Pair[n];
33+
34+
for (int i = 0; i < n; ++i)
35+
numAndIndexes[i] = new Pair<>(nums.get(i), i);
36+
37+
Arrays.sort(numAndIndexes,
38+
Comparator.comparing(Pair<Integer, Integer>::getKey, Comparator.reverseOrder())
39+
.thenComparingInt(Pair<Integer, Integer>::getValue));
40+
41+
for (Pair<Integer, Integer> numAndIndex : numAndIndexes) {
42+
final int num = numAndIndex.getKey();
43+
final int i = numAndIndex.getValue();
44+
45+
final long rangeCount = (long) (i - left[i]) * (right[i] - i);
46+
final long actualCount = Math.min(rangeCount, (long) k);
47+
k -= actualCount;
48+
ans = (int) ((1L * ans * modPow(num, actualCount)) % MOD);
49+
}
50+
51+
return ans;
52+
}
53+
54+
private static final int MOD = 1_000_000_007;
55+
56+
private long modPow(long x, long n) {
57+
if (n == 0)
58+
return 1;
59+
if (n % 2 == 1)
60+
return x * modPow(x, n - 1) % MOD;
61+
return modPow(x * x % MOD, n / 2);
62+
}
63+
64+
private int[] sieveEratosthenes(int n) {
65+
int[] minPrimeFactors = new int[n + 1];
66+
for (int i = 2; i <= n; ++i)
67+
minPrimeFactors[i] = i;
68+
for (int i = 2; i * i < n; ++i)
69+
if (minPrimeFactors[i] == i) // `i` is prime.
70+
for (int j = i * i; j < n; j += i)
71+
minPrimeFactors[j] = Math.min(minPrimeFactors[j], i);
72+
return minPrimeFactors;
73+
}
74+
75+
private int[] getPrimeScores(List<Integer> nums, int[] minPrimeFactors) {
76+
int[] primeScores = new int[nums.size()];
77+
for (int i = 0; i < nums.size(); ++i)
78+
primeScores[i] = getPrimeScore(nums.get(i), minPrimeFactors);
79+
return primeScores;
80+
}
81+
82+
private int getPrimeScore(int num, int[] minPrimeFactors) {
83+
Set<Integer> primeFactors = new HashSet<>();
84+
while (num > 1) {
85+
final int divisor = minPrimeFactors[num];
86+
primeFactors.add(divisor);
87+
while (num % divisor == 0)
88+
num /= divisor;
89+
}
90+
return primeFactors.size();
91+
}
92+
}

0 commit comments

Comments
 (0)