Skip to content

Commit 17ec7f0

Browse files
committed
git
1 parent 3fd1a85 commit 17ec7f0

File tree

11 files changed

+492
-1
lines changed

11 files changed

+492
-1
lines changed

solutions/3154. Find Number of Ways to Reach the K-th Stair/3154.java

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public int waysToReachStair(int k) {
2525
// C(n, k) = C(n - 1, k) + C(n - 1, k - 1)
2626
private int[][] getComb(int n, int k) {
2727
int[][] comb = new int[n + 1][k + 1];
28-
2928
for (int i = 0; i <= n; ++i)
3029
comb[i][0] = 1;
3130
for (int i = 1; i <= n; ++i)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
class Solution {
2+
public:
3+
vector<int> pathExistenceQueries(int n, vector<int>& nums, int maxDiff,
4+
vector<vector<int>>& queries) {
5+
vector<int> ans;
6+
vector<int> sortedNums;
7+
vector<int> indexMap(n);
8+
vector<pair<int, int>> sortedNumAndIndexes;
9+
10+
for (int i = 0; i < n; ++i)
11+
sortedNumAndIndexes.emplace_back(nums[i], i);
12+
13+
ranges::sort(sortedNumAndIndexes);
14+
15+
for (int i = 0; i < n; ++i) {
16+
const auto& [num, sortedIndex] = sortedNumAndIndexes[i];
17+
sortedNums.push_back(num);
18+
indexMap[sortedIndex] = i;
19+
}
20+
21+
const int maxLevel = std::bit_width(static_cast<unsigned>(n)) + 1;
22+
// jump[i][j] := the index of the j-th ancestor of i
23+
vector<vector<int>> jump(n, vector<int>(maxLevel));
24+
25+
int right = 0;
26+
for (int i = 0; i < n; ++i) {
27+
while (right + 1 < n && sortedNums[right + 1] - sortedNums[i] <= maxDiff)
28+
++right;
29+
jump[i][0] = right;
30+
}
31+
32+
for (int level = 1; level < maxLevel; ++level)
33+
for (int i = 0; i < n; ++i) {
34+
const int prevJump = jump[i][level - 1];
35+
jump[i][level] = jump[prevJump][level - 1];
36+
}
37+
38+
for (const vector<int>& query : queries) {
39+
const int u = query[0];
40+
const int v = query[1];
41+
const int uIndex = indexMap[u];
42+
const int vIndex = indexMap[v];
43+
const int start = min(uIndex, vIndex);
44+
const int end = max(uIndex, vIndex);
45+
const int res = minJumps(jump, start, end, maxLevel - 1);
46+
ans.push_back(res == INT_MAX ? -1 : res);
47+
}
48+
49+
return ans;
50+
}
51+
52+
private:
53+
// Returns the minimum number of jumps from `start` to `end` using binary
54+
// lifting.
55+
int minJumps(const vector<vector<int>>& jump, int start, int end, int level) {
56+
if (start == end)
57+
return 0;
58+
if (jump[start][0] >= end)
59+
return 1;
60+
if (jump[start][level] < end)
61+
return INT_MAX;
62+
int j = level;
63+
for (; j >= 0; --j)
64+
if (jump[start][j] < end)
65+
break;
66+
return (1 << j) + minJumps(jump, jump[start][j], end, j);
67+
}
68+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
class Solution {
2+
public int[] pathExistenceQueries(int n, int[] nums, int maxDiff, int[][] queries) {
3+
int[] ans = new int[queries.length];
4+
int[] indexMap = new int[n];
5+
int[] sortedNums = new int[n];
6+
Pair<Integer, Integer>[] sortedNumAndIndexes = new Pair[n];
7+
8+
for (int i = 0; i < n; ++i)
9+
sortedNumAndIndexes[i] = new Pair<>(nums[i], i);
10+
11+
Arrays.sort(sortedNumAndIndexes, Comparator.comparingInt(Pair::getKey));
12+
13+
for (int i = 0; i < n; ++i) {
14+
final int num = sortedNumAndIndexes[i].getKey();
15+
final int sortedIndex = sortedNumAndIndexes[i].getValue();
16+
sortedNums[i] = num;
17+
indexMap[sortedIndex] = i;
18+
}
19+
20+
final int maxLevel = Integer.SIZE - Integer.numberOfLeadingZeros(n) + 1;
21+
// jump[i][j] := the index of the j-th ancestor of i
22+
int[][] jump = new int[n][maxLevel];
23+
24+
int right = 0;
25+
for (int i = 0; i < n; ++i) {
26+
while (right + 1 < n && sortedNums[right + 1] - sortedNums[i] <= maxDiff)
27+
++right;
28+
jump[i][0] = right;
29+
}
30+
31+
for (int level = 1; level < maxLevel; ++level)
32+
for (int i = 0; i < n; ++i) {
33+
final int prevJump = jump[i][level - 1];
34+
jump[i][level] = jump[prevJump][level - 1];
35+
}
36+
37+
for (int i = 0; i < queries.length; ++i) {
38+
final int u = queries[i][0];
39+
final int v = queries[i][1];
40+
final int uIndex = indexMap[u];
41+
final int vIndex = indexMap[v];
42+
final int start = Math.min(uIndex, vIndex);
43+
final int end = Math.max(uIndex, vIndex);
44+
final int res = minJumps(jump, start, end, maxLevel - 1);
45+
ans[i] = res == Integer.MAX_VALUE ? -1 : res;
46+
}
47+
48+
return ans;
49+
}
50+
51+
// Returns the minimum number of jumps from `start` to `end` using binary
52+
// lifting.
53+
private int minJumps(int[][] jump, int start, int end, int level) {
54+
if (start == end)
55+
return 0;
56+
if (jump[start][0] >= end)
57+
return 1;
58+
if (jump[start][level] < end)
59+
return Integer.MAX_VALUE;
60+
int j = level;
61+
for (; j >= 0; --j)
62+
if (jump[start][j] < end)
63+
break;
64+
return (1 << j) + minJumps(jump, jump[start][j], end, j);
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
class Solution:
2+
def pathExistenceQueries(
3+
self,
4+
n: int,
5+
nums: list[int],
6+
maxDiff: int,
7+
queries: list[list[int]],
8+
) -> list[int]:
9+
sortedNumAndIndexes = sorted((num, i) for i, num in enumerate(nums))
10+
sortedNums = [num for num, _ in sortedNumAndIndexes]
11+
indexMap = {originalIndex: sortedIndex for sortedIndex,
12+
(_, originalIndex) in enumerate(sortedNumAndIndexes)}
13+
maxLevel = n.bit_length() + 1
14+
# jump[i][j] is the index of the j-th ancestor of i
15+
jump = [[0] * maxLevel for _ in range(n)]
16+
17+
right = 0
18+
for i in range(n):
19+
while right + 1 < n and sortedNums[right + 1] - sortedNums[i] <= maxDiff:
20+
right += 1
21+
jump[i][0] = right
22+
23+
for level in range(1, maxLevel):
24+
for i in range(n):
25+
prevJump = jump[i][level - 1]
26+
jump[i][level] = jump[prevJump][level - 1]
27+
28+
def minJumps(start: int, end: int, level: int) -> int:
29+
"""
30+
Returns the minimum number of jumps from `start` to `end` using binary
31+
lifting.
32+
"""
33+
if start == end:
34+
return 0
35+
if jump[start][0] >= end:
36+
return 1
37+
if jump[start][level] < end:
38+
return math.inf
39+
for j in range(level, -1, -1):
40+
if jump[start][j] < end:
41+
break
42+
return (1 << j) + minJumps(jump[start][j], end, j)
43+
44+
def minDist(u: int, v: int) -> int:
45+
uIndex = indexMap[u]
46+
vIndex = indexMap[v]
47+
start = min(uIndex, vIndex)
48+
end = max(uIndex, vIndex)
49+
res = minJumps(start, end, maxLevel - 1)
50+
return res if res < math.inf else -1
51+
52+
return [minDist(u, v) for u, v in queries]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
class Solution {
2+
public:
3+
vector<int> queryConversions(vector<vector<int>>& conversions,
4+
vector<vector<int>>& queries) {
5+
const vector<int> units = baseUnitConversions(conversions);
6+
vector<int> ans;
7+
8+
for (const vector<int>& query : queries) {
9+
const int u = query[0];
10+
const int v = query[1];
11+
// By Fermat's little theorem.
12+
ans.push_back(units[v] * modPow(units[u], kMod - 2) % kMod);
13+
}
14+
15+
return ans;
16+
}
17+
18+
private:
19+
static constexpr int kMod = 1'000'000'007;
20+
21+
// Same as 3528. Unit Conversion I
22+
vector<int> baseUnitConversions(vector<vector<int>>& conversions) {
23+
const int n = conversions.size() + 1;
24+
vector<int> res(n);
25+
res[0] = 1;
26+
queue<int> q{{0}};
27+
vector<vector<pair<int, int>>> graph(n);
28+
29+
for (const vector<int>& conversion : conversions) {
30+
const int u = conversion[0];
31+
const int v = conversion[1];
32+
const int factor = conversion[2];
33+
graph[u].emplace_back(v, factor);
34+
}
35+
36+
while (!q.empty()) {
37+
const int u = q.front();
38+
q.pop();
39+
for (const auto& [v, factor] : graph[u]) {
40+
res[v] = (static_cast<long>(res[u]) * factor) % kMod;
41+
q.push(v);
42+
}
43+
}
44+
45+
return res;
46+
}
47+
48+
long modPow(long x, long n) {
49+
if (n == 0)
50+
return 1;
51+
if (n % 2 == 1)
52+
return x * modPow(x % kMod, (n - 1)) % kMod;
53+
return modPow(x * x % kMod, (n / 2)) % kMod;
54+
}
55+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
class Solution {
2+
public int[] queryConversions(int[][] conversions, int[][] queries) {
3+
int[] units = baseUnitConversions(conversions);
4+
int[] ans = new int[queries.length];
5+
6+
for (int i = 0; i < queries.length; ++i) {
7+
final int u = queries[i][0];
8+
final int v = queries[i][1];
9+
// By Fermat's little theorem.
10+
ans[i] = (int) ((long) units[v] * modPow(units[u], MOD - 2) % MOD);
11+
}
12+
13+
return ans;
14+
}
15+
16+
private static final int MOD = 1_000_000_007;
17+
18+
private int[] baseUnitConversions(int[][] conversions) {
19+
final int n = conversions.length + 1;
20+
int[] ans = new int[n];
21+
ans[0] = 1;
22+
Queue<Integer> q = new ArrayDeque<>(Arrays.asList(0));
23+
List<Pair<Integer, Integer>>[] graph = new List[n];
24+
25+
for (int i = 0; i < n; i++)
26+
graph[i] = new ArrayList<>();
27+
28+
for (int[] conversion : conversions) {
29+
final int u = conversion[0];
30+
final int v = conversion[1];
31+
final int factor = conversion[2];
32+
graph[u].add(new Pair<>(v, factor));
33+
}
34+
35+
while (!q.isEmpty()) {
36+
final int u = q.poll();
37+
for (Pair<Integer, Integer> pair : graph[u]) {
38+
final int v = pair.getKey();
39+
final int factor = pair.getValue();
40+
ans[v] = (int) ((long) ans[u] * factor % MOD);
41+
q.offer(v);
42+
}
43+
}
44+
45+
return ans;
46+
}
47+
48+
private int modPow(long x, long n) {
49+
if (n == 0)
50+
return 1;
51+
if (n % 2 == 1)
52+
return (int) (x * modPow(x % MOD, (n - 1)) % MOD);
53+
return modPow(x * x % MOD, (n / 2)) % MOD;
54+
}
55+
}
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class Solution:
2+
def queryConversions(
3+
self,
4+
conversions: list[list[int]],
5+
queries: list[list[int]]
6+
) -> list[int]:
7+
self.MOD = 1_000_000_007
8+
units = self._baseUnitConversions(conversions)
9+
# By Fermat's little theorem.
10+
return [units[v] * self._modPow(units[u], self.MOD - 2) % self.MOD
11+
for u, v in queries]
12+
13+
# Same as 3528. Unit Conversion I
14+
def _baseUnitConversions(self, conversions: list[list[int]]) -> list[int]:
15+
n = len(conversions) + 1
16+
res = [0] * n
17+
res[0] = 1
18+
q = collections.deque([0])
19+
graph = [[] for _ in range(n)]
20+
21+
for u, v, factor in conversions:
22+
graph[u].append((v, factor))
23+
24+
while q:
25+
u = q.popleft()
26+
for v, factor in graph[u]:
27+
res[v] = (res[u] * factor) % self.MOD
28+
q.append(v)
29+
30+
return res
31+
32+
def _modPow(self, x: int, n: int) -> int:
33+
if n == 0:
34+
return 1
35+
if n % 2 == 1:
36+
return x * self._modPow(x, n - 1) % self.MOD
37+
return self._modPow(x * x % self.MOD, n // 2)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution:
2+
def minTravelTime(
3+
self,
4+
l: int,
5+
n: int,
6+
k: int,
7+
position: list[int],
8+
time: list[int]
9+
) -> int:
10+
prefix = list(itertools.accumulate(time))
11+
12+
@functools.lru_cache(None)
13+
def dp(i: int, skips: int, last: int) -> int:
14+
"""
15+
Returns the minimum travel time to reach the last stop from i-th stop,
16+
with `skips` skips remaining, and the last stop being `last`.
17+
"""
18+
if i == n - 1:
19+
return 0 if skips == 0 else math.inf
20+
res = math.inf
21+
rate = prefix[i] - (prefix[last - 1] if last > 0 else 0)
22+
end = min(n - 1, i + skips + 1)
23+
for j in range(i + 1, end + 1):
24+
distance = position[j] - position[i]
25+
res = min(res, distance * rate + dp(j, skips - (j - i - 1), i + 1))
26+
return res
27+
28+
return dp(0, k, 0)

0 commit comments

Comments
 (0)