Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define sc(a) scanf("%d",&a)
- #define sc2(a,b) scanf("%d%d",&a,&b)
- #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
- #define pri(x) printf("%d\n",x)
- #define prie(x) printf("%d ",x)
- #define prif() printf("\n")
- #define sz(x) (int)((x).size())
- #define mp make_pair
- #define pb push_back
- #define f first
- #define s second
- #define BUFF ios::sync_with_stdio(false)
- typedef long long int ll;
- typedef pair<int, int> ii;
- typedef vector<int> vi;
- typedef vector<vi> vvi;
- typedef vector<ii> vii;
- const int INF = 0x3f3f3f3f;
- const ll LINF = 0x3f3f3f3f3f3f3f3fll;
- const int MAX = 3e5+10;
- vvi g(MAX);
- vvi w(MAX);
- int x, y;
- int n, q;
- int B[510][510];
- vector<pair<int, ii> > ar;
- int v[MAX];
- void build() {
- for (int i = 0; i < n; i++) v[i] = i;
- }
- int find(int k) {
- return v[k] == k ? k : v[k] = find(v[k]);
- }
- void une(int a, int b) {
- v[find(a)] = find(b);
- }
- int get(int a, int b) {
- return (a-1)*y + (b-1);
- }
- void aresta(int a, int b, int c) {
- ar.pb({c, {a, b}});
- n = max({n, a+1, b+1});
- }
- void monta() {
- sc3(x, y, q);
- for (int i = 0; i < x*y; i++) sc(B[i/y][i%y]);
- for (int i = 1; i <= x; i++) for (int j = 1; j <= y; j++) {
- if (i < x) aresta(get(i, j), get(i+1, j), max(B[i-1][j-1], B[i][j-1]));
- if (j < y) aresta(get(i, j), get(i, j+1), max(B[i-1][j-1], B[i-1][j]));
- }
- }
- void kruskal() {
- sort(ar.begin(), ar.end());
- build();
- for (auto i : ar) {
- int a = i.s.f, b = i.s.s, c = i.f;
- if (find(a) == find(b)) continue;
- une(a, b);
- g[a].pb(b);
- w[a].pb(c);
- g[b].pb(a);
- w[b].pb(c);
- }
- }
- int pai[30][MAX], p;
- int sobe[30][MAX];
- int in[MAX], out[MAX];
- void dfs(int k, int pa = -1) {
- in[k] = p++;
- for (int i = 0; i < g[k].size(); i++) if (g[k][i] != pa) {
- pai[0][g[k][i]] = k;
- sobe[0][g[k][i]] = w[k][i];
- dfs(g[k][i], k);
- }
- out[k] = p;
- }
- void build_lca() {
- for (int i = 0; i < n; i++) pai[0][i] = i;
- dfs(0);
- for (int k = 1; k < 30; k++) for (int i = 0; i < n; i++) {
- pai[k][i] = pai[k-1][pai[k-1][i]];
- sobe[k][i] = max(sobe[k-1][i], sobe[k-1][pai[k-1][i]]);
- }
- }
- bool anc(int a, int b) {
- return in[a] <= in[b] and out[a] >= out[b];
- }
- int lca(int a, int b) {
- if (anc(a, b)) return a;
- if (anc(b, a)) return b;
- for (int k = 29; k+1; k--) if (!anc(pai[k][a], b)) a = pai[k][a];
- return pai[0][a];
- }
- int dist(int a, int b) {
- int l = lca(a, b);
- if (a == b and a == l) return -1;
- int ret = -1;
- for (int k = 29; k+1; k--) if (!anc(pai[k][a], b)) {
- ret = max(ret, sobe[k][a]);
- a = pai[k][a];
- }
- if (a != l) {
- ret = max(ret, sobe[0][a]);
- a = pai[0][a];
- }
- return max(ret, dist(b, a));
- }
- int main() {
- monta();
- kruskal();
- build_lca();
- while (q--) {
- int a, b, c, d; sc2(a, b), sc2(c, d);
- if (get(a, b) == get(c, d)) pri(B[a-1][b-1]);
- else pri(dist(get(a, b), get(c, d)));
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement