Nu aveti permisiuni pentru a descarca fisierul grader_test49.ok

Cod sursa(job #2024340)

Utilizator gabib97Gabriel Boroghina gabib97 Data 20 septembrie 2017 14:12:45
Problema Lowest Common Ancestor Scor 100
Compilator java Status done
Runda Arhiva educationala Marime 2.65 kb
import java.util.*;
import java.io.*;

public class Main {
    static int n, m, nr;
    static int[] t, euler, f, h, lg;
    static int[][] r;
    static Vector<Integer>[] G;

    static void DFS(int s) {
        euler[++nr] = s;

        for (int x : G[s])
            if (x != t[s]) {
                h[x] = h[s] + 1;
                DFS(x);
                euler[++nr] = s;
            }
    }

    static void rmq() {
        int i, j, p;
        DFS(1);
        lg = new int[nr + 1];
        r = new int[nr + 1][25];

        for (i = nr; i >= 1; i--) {
            f[euler[i]] = i;
            r[i][0] = euler[i];
        }

        // compute rmq
        for (i = 1, p = 1; (p << 1) <= nr; i++, p <<= 1)
            for (j = 1; j <= nr - (p << 1) + 1; j++) {

                if (h[r[j][i - 1]] < h[r[j + p][i - 1]])
                    r[j][i] = r[j][i - 1];
                else
                    r[j][i] = r[j + p][i - 1];
            }
        // compute log2
        j = -1;
        p = 1;
        for (i = 1; i <= nr; i++) {
            if (i == p) {
                j++;
                p <<= 1;
            }
            lg[i] = j;
        }
    }

    static int query(int x, int y) {
        int q = lg[y - x + 1];

        if (h[r[x][q]] < h[r[y - (1 << q) + 1][q]])
            return r[x][q];

        return r[y - (1 << q) + 1][q];
    }

    public static void main(String[] args) throws IOException {
        Scan cin = new Scan("lca.in");
        PrintWriter cout = new PrintWriter("lca.out");
        int i;

        n = cin.nextInt();
        m = cin.nextInt();
        t = new int[n + 1];
        f = new int[n + 1];
        h = new int[n + 1];
        euler = new int[2 * n + 1];
        G = new Vector[n + 1];
        for (i = 1; i <= n; i++) G[i] = new Vector<>();

        for (i = 2; i <= n; i++) {
            t[i] = cin.nextInt();
            G[t[i]].add(i);
        }
        rmq();

        int x, y;
        while (m-- != 0) {
            x = cin.nextInt();
            y = cin.nextInt();
            cout.print(query(Math.min(f[x], f[y]), Math.max(f[x], f[y])) + "\n");
        }

        cout.close();
    }

    private static class Scan {
        BufferedReader bufferedReader;
        StringTokenizer st;

        Scan(String file) throws FileNotFoundException {
            bufferedReader = new BufferedReader(new FileReader(file));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreElements())
                st = new StringTokenizer(bufferedReader.readLine());

            return st.nextToken();
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
    }
}