Pagini recente » Cod sursa (job #680154) | Cod sursa (job #2697581) | Borderou de evaluare (job #2024269) | Cod sursa (job #2772923) | Cod sursa (job #1456213)
#include <fstream>
#include <array>
#include <vector>
#include <cmath>
using namespace std;
void make_euler(const vector<vector<int> >& fii,
vector<int>& euler, vector<int>& first_aparition,
vector<int>& adanc, const int cur = 0, const int ad_cur = 0){
first_aparition[cur] = euler.size();
euler.push_back(cur);
adanc[cur] = ad_cur;
for(const auto next : fii[cur]){
make_euler(fii, euler, first_aparition, adanc, next, ad_cur+1);
euler.push_back(cur); } }
template <typename Cmp>
class rmq{
vector<array<int, 19> > buf;
Cmp cmp;
public:
rmq(const vector<int>& v, Cmp c):
buf(v.size()),
cmp(c){
for(int i = 0; i < buf.size(); ++i){
buf[i][0] = v[i]; }
for(int adanc = 1; adanc < 19; ++adanc){
const int marime = 1<<adanc,
delta = 1<<(adanc-1);
for(int i = 0; i+marime <= buf.size(); ++i){
buf[i][adanc] = min(buf[i][adanc-1],
buf[i+delta][adanc-1],
cmp); } } }
int query(const int st, const int dr){
const int marime = log2(dr-st+1),
delta = 1<<marime;
return min(buf[st][marime], buf[dr-delta+1][marime]); } };
int main(){
ifstream f("lca.in");
ofstream g("lca.out");
int n, m;
f >> n >> m;
vector<vector<int> > fii(n);
vector<int> euler, first_aparition(n), adanc(n);
euler.reserve(2*n);
for(int i = 1, x; i < n; ++i){
f >> x;
fii[x-1].push_back(i); }
auto cmp = [&adanc](const int a, const int b){
return adanc[a] < adanc[b]; };
make_euler(fii, euler, first_aparition, adanc);
rmq<decltype(cmp)> r(euler, cmp);
for(int i = 0, a, b; i < m; ++i){
f >> a >> b;
--a, --b;
if(first_aparition[a] > first_aparition[b]){
swap(a, b); }
g << (r.query(first_aparition[a], first_aparition[b])+1) << '\n'; }
return 0; }