Pagini recente » Cod sursa (job #1217401) | Cod sursa (job #2760739) | Cod sursa (job #888991) | Cod sursa (job #1187651) | Cod sursa (job #603638)
Cod sursa(job #603638)
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <string.h>
#define MAXN 100000
#define DUMMY 0x80000000
#define IS_DUMMY(node) ((node)&DUMMY)
#define GET_NODE_FROM_DUMMY(node) ((node)&(~DUMMY))
using namespace std;
typedef unsigned int uint32;
int E[2*MAXN+1], L[2*MAXN+1], H[MAXN], pred[MAXN+1];
vector<int> tree[MAXN+1];
int mat[2*MAXN+1][18];
// range minimum query code
int computeLog2(const uint32 num)
{
uint32 i;
for (i=0; 1<<i <= num; ++i) ;
return i-1;
}
void preprocess(const int *const a, const uint32 size)
{
for (uint32 i=0; i<size; ++i)
mat[i][0] = i;
for (uint32 j=1; (1<<j) < size; ++j)
for (uint32 i=0; i+(1<<j)-1 < size; ++i)
if (a[mat[i][j-1]] <= a[mat[i+(1<<(j-1))][j-1]])
mat[i][j] = mat[i][j-1];
else
mat[i][j] = mat[i+(1<<(j-1))][j-1];
}
int query(const int *const a, const uint32 i, const uint32 j)
{
const uint32 l2 = j-i>0 ? computeLog2(j-i) : 0;
if (a[mat[i][l2]] <= a[mat[j-(1<<l2)+1][l2]])
return mat[i][l2];
return mat[j-(1<<l2)+1][l2];
}
// compute euler path
void DFS(const int node, const int level, int& el)
{
E[el] = node;
L[el++] = level;
//if (H[node] == -1)
H[node] = el-1;
for (int i=0; i<tree[node].size(); ++i)
{
DFS(tree[node][i], level+1, el);
E[el] = node;
L[el++] = level;
}
}
int computeEulerTour
( const vector<vector<int> >& tree,
int *const E,
int *const L,
int *const H,
const int *const pred,
const int n)
{
int e=0, l=0;
stack<pair<int, const int> > st;
st.push(make_pair(0,0));
while (!st.empty())
{
const pair<int, const int> node = st.top();
st.pop();
if (!IS_DUMMY(node.first))
{
E[e++] = node.first;
L[l++] = node.second;
H[node.first] = e-1;
st.push(make_pair(node.first|DUMMY, node.second));
for (int i=tree[node.first].size()-1; i>=0; --i)
{
st.push(make_pair(tree[node.first][i],node.second+1));
}
}
else if (pred[GET_NODE_FROM_DUMMY(node.first)] != -1)
{
E[e++] = pred[GET_NODE_FROM_DUMMY(node.first)];
L[l++] = node.second-1;
}
}
return l;
}
int main()
{
int n, m, l;
fstream fin("lca.in", fstream::in);
fstream fout("lca.out", fstream::out);
fin >> n >> m;
//cout << n << " " << m << endl;
//mat = new int*[2*MAXN+1];
/*for (uint32 i=0; i<2*MAXN; ++i)
{
mat[i] = new int[2*computeLog2(MAXN)+1];
}*/
/*E = new int[2*n+1];
L = new int[2*n+1];
H = new int[n+1];
pred = new int[n+1];*/
//tree.resize(n);
//memset(H, 0xFF, n*sizeof(int));
//pred[0] = -1;
for (int i=1; i<n; ++i)
{
int x;
fin >> x;
tree[x-1].push_back(i);
//pred[i] = x-1;
}
/*for (int i=0; i<n; ++i)
{
cout << i << " --> ";
for (int j=0; j<tree[i].size(); ++j)
{
cout << tree[i][j] << " ";
}
cout << endl;
}
for (int i=0; i<n; ++i)
{
cout << pred[i] << " ";
}
cout << endl;*/
//l = computeEulerTour(tree, E, L, H, pred, n);
l = 0;
DFS(0,0,l);
/*cout << "E: ";
for (int i=0; i<l; ++i)
{
cout << E[i] << " ";
}
cout << endl << endl;
cout << "L: ";
for (int i=0; i<l; ++i)
{
cout << L[i] << " ";
}
cout << endl << endl;
cout << "H: ";
for (int i=0; i<n; ++i)
{
cout << H[i] << " ";
}
cout << endl;*/
preprocess(L, l);
for (int i=0; i<m; ++i)
{
int u, v;
fin >> u >> v;
//cout << u << " " << v << endl;
if (H[u-1] < H[v-1])
fout << E[query(L,H[u-1],H[v-1])]+1 << "\n";
else
fout << E[query(L,H[v-1],H[u-1])]+1 << "\n";
}
fin.close();
fout.close();
return 0;
}