Cod sursa(job #2959954)

Utilizator tomaionutIDorando tomaionut Data 3 ianuarie 2023 11:51:44
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.54 kb
#include <bits/stdc++.h>
#include <unordered_set>

using namespace std;

ifstream fin("pirati.in");
ofstream fout("pirati.out");

int n, m, q, c, k;
char s[1005][1005];
int viz[1005][1005];
int dx[] = { 0, 0, 1, 1, 1, -1, -1, -1 };
int dy[] = { 1, -1, -1, 0, 1, -1, 0, 1 };
int e[1000005], niv[1000005], poz[100005], rmq[21][1000005], p2[1000005];
unordered_set <int> a[100005];
bool OK(int i, int j)
{
    return (1 <= i and i <= n and 1 <= j and j <= m);
}

void Fill(int x, int y, int col)
{
    int i, j;
    viz[x][y] = col;
    for (int dir = 0; dir <= 7; dir++)
    {
        i = x + dx[dir];
        j = y + dy[dir];
        if (OK(i, j))
        {
            if (viz[i][j] == 0 and s[i][j] == s[x][y])
                Fill(i, j, col);
            else if (s[i][j] != s[x][y] and viz[i][j])
            {
                a[viz[i][j]].insert(viz[x][y]);
                a[viz[x][y]].insert(viz[i][j]);
            }
        }
    }
}

void Dfs(int x, int lvl, int last)
{
    e[++k] = x;
    niv[k] = lvl;
    poz[x] = k;
    for (auto w : a[x])
        if (w != last)
        {
            Dfs(w, lvl + 1, x);
            e[++k] = x;
            niv[k] = lvl;
            poz[x] = k;
        }
}

int Query(int i, int j)
{
    i = poz[i];
    j = poz[j];
    if (i > j)
        swap(i, j);
    int lg = p2[j - i + 1];
    //cout << lg << "*";
    //cout << rmq[lg][i] << " " << rmq[lg][j - (1 << lg) + 1] << " ";
    if (niv[rmq[lg][i]] < niv[rmq[lg][j - (1 << lg) + 1]])
        return e[rmq[lg][i]];
    return e[rmq[lg][j - (1 << lg) + 1]];
}

int main()
{
    int i, j, x1, y1, x2, y2;
    fin >> n >> m >> q;
    for (i = 1; i <= n; i++)
        fin >> (s[i] + 1);

    for (i = 1; i <= n; i++)
        for (j = 1; j <= m; j++)
            if (viz[i][j] == 0)
            {
                c++;
                Fill(i, j, c);
            }

    Dfs(1, 1, 0);

    p2[1] = 0;
    for (i = 2; i <= k; i++)
        p2[i] = 1 + p2[i / 2];
      
    for (i = 1; i <= k; i++)
        rmq[0][i] = i;

    for (i = 1; i <= p2[k]; i++)
        for (j = 1; j <= k - (1 << i) + 1; j++)
        {
            rmq[i][j] = rmq[i - 1][j];
            if (niv[rmq[i - 1][j]] > niv[rmq[i - 1][j + (1 << (i - 1))]])
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }

    while (q--)
    {
        fin >> x1 >> y1 >> x2 >> y2;
        i = viz[x1][y1];
        j = viz[x2][y2];
        fout << (niv[i] + niv[j]) / 2 - niv[Query(i, j)] << "\n";
    }



    return 0;
}