Skip to content

[pull] master from wisdompeak:master #327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using ll = long long;
const int MAXN = 100000;
const int LOGN = 17;
class Solution {
int up[MAXN][LOGN+1];
public:
ll stepUp(int u, int k) {
for (int i=LOGN; i>=0; i--) {
if ((k>>i)&1) {
u = up[u][i];
}
}
return u;
}

vector<int> pathExistenceQueries(int n, vector<int>& nums, int maxDiff, vector<vector<int>>& queries) {
vector<pair<int,int>>arr;
for (int i=0; i<nums.size(); i++) {
arr.push_back({nums[i], i});
}
sort(arr.begin(), arr.end());

unordered_map<int,int>idx;
for (int i=0; i<n; i++) {
idx[arr[i].second] = i;
}

int j = 0;
for (int i=0; i<n; i++) {
while (j<n && arr[j].first-arr[i].first<=maxDiff) {
j++;
}
up[i][0] = j-1;
}

for(int k = 1; k <= LOGN; k++) {
for(int v = 0; v < n; v++) {
up[v][k] = up[up[v][k-1]][k-1];
}
}

vector<int>rets;
for (auto& q: queries) {
if (q[0]==q[1]) {
rets.push_back(0);
continue;
}
int u = idx[q[0]], v = idx[q[1]];
if (u>v) swap(u,v);

int low = 1, high = 1e5;
while (low < high) {
int mid = low + (high-low)/2;
int k = stepUp(u, mid);
if (arr[k].first >= arr[v].first)
high = mid;
else
low = mid+1;
}
int k = stepUp(u, low);
if (arr[k].first >= arr[v].first)
rets.push_back(low);
else
rets.push_back(-1);
}

return rets;
}
};
13 changes: 13 additions & 0 deletions Binary_Search/3534.Path-Existence-Queries-in-a-Graph-II/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
### 3534.Path-Existence-Queries-in-a-Graph-II

我们将所有的数按照从小到大的顺序排列之后,本题的问题就是:给出任意两点u<v,从u跳跃至v最少需要多少步?

不难发现,通过双指针,我们可以知道任意一点x能向右跳跃的最远位置y。事实上我们只需要关心{x,y}之间的路径,而不用在意x到其他可跳跃位置的路径。这是因为对于其他任何早于y的位置z,根据定义,必然也可以从x到z的一步跳跃。

因此,对于任意的query={u,v},如果问能否用k步实现跨越,其实只需要考察k次上述定义的跳跃路径:u->x, x-y, y->z, ... 如果最终的位置能够超越v,那么答案就是肯定。反之,如果问{u,v}之间最少用多少步可以实现跨越,那么显然我们可以用二分搜值再验证,从而逼近最优解。

对于验证的过程,我们如果线性地去模拟k次跳跃,时间是不够的。因此我们会用到binary lifting(倍增)算法。不仅计算x和它一步所能跳跃的最远点y之间的路径,而且还预处理`up[x][k]`,表示从x点往右跳跃`2^k`步所能到达的最远位置,其中k最大值是17即可。在准备好了up数组之后,二分搜值的验证过程只需要log(N)次的跳转即可。




1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
[2836.Maximize-Value-of-Function-in-a-Ball-Passing-Game](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2836.Maximize-Value-of-Function-in-a-Ball-Passing-Game) (H)
[2846.Minimum-Edge-Weight-Equilibrium-Queries-in-a-Tree](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2846.Minimum-Edge-Weight-Equilibrium-Queries-in-a-Tree) (H)
[2851.String-Transformation](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2851.String-Transformation) (H+)
[3534.Path-Existence-Queries-in-a-Graph-II](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/3534.Path-Existence-Queries-in-a-Graph-II) (H)
[3553.Minimum-Weighted-Subgraph-With-the-Required-Paths-II](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/3553.Minimum-Weighted-Subgraph-With-the-Required-Paths-II) (H)
[3585.Find-Weighted-Median-Node-in-Tree](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/3585.Find-Weighted-Median-Node-in-Tree) (H)
* ``Binary Search by Value``
Expand Down