Pagini recente » rhino-pilot | Cod sursa (job #2217590) | Cod sursa (job #2753813) | Cod sursa (job #938964) | Cod sursa (job #2818350)
#include <bits/stdc++.h>
#define MAXN 1000003
#define MAXQ 1000003
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector<int> v[MAXN]; // contine fiii fiecarui nod
vector<int> euler; // contine sirul reprezentarii Euler a arborelui
vector<int> h; // contine inaltimile pt fiecare nod din reprezentarea Euler
int first[MAXN]; // contine prima pozitie din reprezentarea Euler pentru fiecare nod.
int arb[MAXN << 4]; // arborele de intervale pe care vom face query-uri
int n, nrq; // numarul de noduri si numarul de query-uri
int sol, solh; // nodul solutie si inaltimea sa
int k; // dimensiunea vectorilor din repr Euler
int st, dr;
void read()
{
f >> n >> nrq;
for (int i = 2; i <= n; i++)
{
int parent;
f >> parent;
v[parent].push_back(i);
}
}
void make_euler(int nod, int height)
{
euler.push_back(nod);
h.push_back(height);
first[nod] = euler.size() - 1;
for (long unsigned int i = 0; i < v[nod].size(); i++)
{
make_euler(v[nod][i], height + 1);
euler.push_back(nod);
h.push_back(height);
}
}
void build(int nod, int first, int last)
{
if (first == last)
{
arb[nod] = first;
return;
}
int mij = (first + last) / 2;
int nodst = 2 * nod, noddr = 2 * nod + 1;
build(nodst, first, mij);
build(noddr, mij + 1, last);
if (h[arb[nodst]] <= h[arb[noddr]])
arb[nod] = arb[nodst];
else
arb[nod] = arb[noddr];
}
void query(int nod, int first, int last)
{
if (st <= first && dr >= last)
{
if (h[arb[nod]] < solh)
{
sol = euler[arb[nod]];
solh = h[arb[nod]];
}
return;
}
int mij = (first + last) / 2;
if (st <= mij)
query(2 * nod, first, mij);
if (mij < dr)
query(2 * nod + 1, mij + 1, last);
}
int LCA(int x, int y)
{
st = first[x];
dr = first[y];
if (st > dr)
swap(st, dr);
sol = INT_MAX;
solh = INT_MAX;
query(1, 0, k - 1);
return sol;
}
int main()
{
// auto start = chrono::high_resolution_clock::now();
read();
make_euler(1, 0);
k = euler.size();
build(1, 0, k - 1);
for (int i = 0; i < nrq; i++)
{
int nod1, nod2;
f >> nod1 >> nod2;
g << LCA(nod1, nod2) << '\n';
}
/*auto stop = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::milliseconds>(stop - start);
cout << "\nTimp de rulare: " << duration.count() << " milisecunde\n";*/
f.close();
g.close();
return 0;
}