Skip to content

Commit

Permalink
[pre-commit.ci] auto fixes from pre-commit.com hooks
Browse files Browse the repository at this point in the history
for more information, see https://pre-commit.ci
  • Loading branch information
pre-commit-ci[bot] committed May 19, 2024
1 parent 539e61f commit b4b8969
Showing 1 changed file with 125 additions and 119 deletions.
244 changes: 125 additions & 119 deletions content/5_Plat/Geo_Pri.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -397,21 +397,24 @@ will run on $n^2$ edges, which causes TLE.
<CPPSection>

```cpp
#include <iostream>
#include <functional>
#include <iostream>
#include <unordered_set>
#include <vector>

using namespace std;

struct point { int x, y, idx; };
struct point {
int x, y, idx;
};

// BeginCodeSnip{DSU}
class DisjointSets {
private:
private:
vector<int> parents;
vector<int> sizes;
public:

public:
DisjointSets(int size) : parents(size), sizes(size, 1) {
for (int i = 0; i < size; i++) { parents[i] = i; }
}
Expand All @@ -438,137 +441,140 @@ public:
};
// EncCodeSnip


// BeginCodeSnip{Binary jumping}
class BinaryJumping {
private:
const int MAX_LOG = 20;
vector<vector<int>> up;
vector<vector<int>> val;
vector<int> depth;
public:
BinaryJumping(vector<vector<pair<int, int>>> &tree) {
up.resize((int)tree.size());
depth.resize((int)tree.size());
val.resize((int)tree.size());
for(int i = 0; i < (int)tree.size(); i++) {
up[i].resize(MAX_LOG);
val[i].resize(MAX_LOG);
}
dfs(0, 0, tree);
}
void dfs(int node, int parent, vector<vector<pair<int, int>>> &tree) {
depth[node] = depth[parent] + 1;
up[node][0] = parent;
for(int i = 1; i < MAX_LOG; i++) {
up[node][i] = up[up[node][i - 1]][i - 1];
val[node][i] = max(val[node][i - 1], val[up[node][i - 1]][i - 1]);
}
for(auto [son, dist] : tree[node]) {
if(son == parent) { continue; }
val[son][0] = dist;
dfs(son, node, tree);
}
}
int jump(int x, int d) {
for(int i = 0; (1 << i) <= d; i++) {
if((1 << i) & d) {
x = up[x][i];
}
}
return x;
}
int get_lca(int x, int y) {
if(depth[x] < depth[y]) { swap(x, y); }
x = jump(x, depth[x] - depth[y]);
if(x == y) { return x; }
for(int i = MAX_LOG; i >= 0; i--){
if(up[x][i] != up[y][i]) {
x = up[x][i];
y = up[y][i];
}
}
return up[x][1];
}
int query(int x, int y) {
int z = get_lca(x, y), ans = 0, d;
d = depth[x] - depth[z];
for(int i = 0; (1 << i) <= d; i++){
if((1 << i) & d) {
ans = max(ans, val[x][i]);
x = up[x][i];
}
}
d = depth[y] - depth[z];
for(int i = 0; (1 << i) <= d; i++){
if((1 << i) & d) {
ans = max(ans, val[y][i]);
y = up[y][i];
}
}
return ans;
}
private:
const int MAX_LOG = 20;
vector<vector<int>> up;
vector<vector<int>> val;
vector<int> depth;

public:
BinaryJumping(vector<vector<pair<int, int>>> &tree) {
up.resize((int)tree.size());
depth.resize((int)tree.size());
val.resize((int)tree.size());
for (int i = 0; i < (int)tree.size(); i++) {
up[i].resize(MAX_LOG);
val[i].resize(MAX_LOG);
}
dfs(0, 0, tree);
}
void dfs(int node, int parent, vector<vector<pair<int, int>>> &tree) {
depth[node] = depth[parent] + 1;
up[node][0] = parent;
for (int i = 1; i < MAX_LOG; i++) {
up[node][i] = up[up[node][i - 1]][i - 1];
val[node][i] = max(val[node][i - 1], val[up[node][i - 1]][i - 1]);
}
for (auto [son, dist] : tree[node]) {
if (son == parent) { continue; }
val[son][0] = dist;
dfs(son, node, tree);
}
}
int jump(int x, int d) {
for (int i = 0; (1 << i) <= d; i++) {
if ((1 << i) & d) { x = up[x][i]; }
}
return x;
}
int get_lca(int x, int y) {
if (depth[x] < depth[y]) { swap(x, y); }
x = jump(x, depth[x] - depth[y]);
if (x == y) { return x; }
for (int i = MAX_LOG; i >= 0; i--) {
if (up[x][i] != up[y][i]) {
x = up[x][i];
y = up[y][i];
}
}
return up[x][1];
}
int query(int x, int y) {
int z = get_lca(x, y), ans = 0, d;
d = depth[x] - depth[z];
for (int i = 0; (1 << i) <= d; i++) {
if ((1 << i) & d) {
ans = max(ans, val[x][i]);
x = up[x][i];
}
}
d = depth[y] - depth[z];
for (int i = 0; (1 << i) <= d; i++) {
if ((1 << i) & d) {
ans = max(ans, val[y][i]);
y = up[y][i];
}
}
return ans;
}
};
// EndCodeSnip

// Manhattan distance
int dist(const point &a, const point &b) {
return abs(a.x - b.x) + abs(a.y - b.y);
return abs(a.x - b.x) + abs(a.y - b.y);
}

vector<pair<point, point>> compute_mst(vector<pair<point, point>> edges) {
sort(edges.begin(), edges.end(), [&](pair<point, point> a, pair<point, point> b) {
return dist(a.first, a.second) < dist(b.first, b.second);
});
DisjointSets ds((int)edges.size());
vector<pair<point, point>> mst;
for(int i = 0; i < (int)edges.size(); i++) {
if(ds.connected(edges[i].first.idx, edges[i].second.idx)) { continue; }
ds.unite(edges[i].first.idx, edges[i].second.idx);
mst.push_back(edges[i]);
}
return mst;
sort(edges.begin(), edges.end(),
[&](pair<point, point> a, pair<point, point> b) {
return dist(a.first, a.second) < dist(b.first, b.second);
});
DisjointSets ds((int)edges.size());
vector<pair<point, point>> mst;
for (int i = 0; i < (int)edges.size(); i++) {
if (ds.connected(edges[i].first.idx, edges[i].second.idx)) { continue; }
ds.unite(edges[i].first.idx, edges[i].second.idx);
mst.push_back(edges[i]);
}
return mst;
}

void test_case() {
int n;
cin >> n;
vector<point> points;
for(int i = 0; i < n; i++) {
int x, y;
cin >> x >> y;
points.push_back({x, y, i});
}
vector<pair<point, point>> mst;
for(int i = 0; i < n; i++) {
for(int j = i + 1; j < n; j++) {
mst.push_back({points[i], points[j]});
}
}
mst = compute_mst(mst);
vector<vector<pair<int, int>>> tree(n);
for(pair<point, point> edge : mst) {
tree[edge.first.idx].push_back({edge.second.idx, dist(points[edge.first.idx], points[edge.second.idx])});
tree[edge.second.idx].push_back({edge.first.idx, dist(points[edge.first.idx], points[edge.second.idx])});
// cout << edge.first.idx << ' ' << edge.second.idx << '\n';
}
int q;
BinaryJumping lca(tree);
cin >> q;
while (q--) {
int x, y;
cin >> x >> y;
x--; y--;
cout << lca.query(x, y) << '\n';
}

int n;
cin >> n;
vector<point> points;
for (int i = 0; i < n; i++) {
int x, y;
cin >> x >> y;
points.push_back({x, y, i});
}
vector<pair<point, point>> mst;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
mst.push_back({points[i], points[j]});
}
}
mst = compute_mst(mst);
vector<vector<pair<int, int>>> tree(n);
for (pair<point, point> edge : mst) {
tree[edge.first.idx].push_back(
{edge.second.idx,
dist(points[edge.first.idx], points[edge.second.idx])});
tree[edge.second.idx].push_back(
{edge.first.idx,
dist(points[edge.first.idx], points[edge.second.idx])});
// cout << edge.first.idx << ' ' << edge.second.idx << '\n';
}
int q;
BinaryJumping lca(tree);
cin >> q;
while (q--) {
int x, y;
cin >> x >> y;
x--;
y--;
cout << lca.query(x, y) << '\n';
}
}

int main() {
int t;
cin >> t;
while(t--) { test_case(); }
return 0;
int t;
cin >> t;
while (t--) { test_case(); }
return 0;
}
```

Expand Down

0 comments on commit b4b8969

Please sign in to comment.