Pagini recente » Cod sursa (job #2305108) | Cod sursa (job #3174682) | Cod sursa (job #2686106) | Cod sursa (job #8961) | Cod sursa (job #682534)
Cod sursa(job #682534)
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <cstdlib>
#define MAXN 250001
using namespace std;
typedef unsigned int uint32;
typedef vector<vector<int> >Graph;
Graph graph;
int LookupTable[] =
{
31, 30, 29, 28, 27, 26, 25, 24,
23, 22, 21, 20, 19, 18, 17, 16,
15, 14, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1, 0
};
struct Identity
{
Identity() :
level(0),
id(0)
{}
Identity(const unsigned char l, const int iid) :
level(l),
id(iid)
{}
unsigned char level;
int id;
};
inline int GetMSB(const int mask)
{
unsigned long res=0;
#ifdef _MSC_VER
_BitScanReverse(&res, mask);
#else
res = LookupTable[__builtin_clz(mask)];
#endif
return res;
}
char matAncestorsSize[MAXN];
int matAncestors[19][MAXN];
int Query(int id, int degree)
{
if (!degree)
return id;
while (degree && matAncestorsSize[id])
{
const int idMask = (1<<matAncestorsSize[id])-1;
int msbIndex = GetMSB(degree & idMask);
//cout << "MSB = " << msbIndex << endl;
degree -= (1<<msbIndex);
id = matAncestors[msbIndex][id];
//cout << id << endl;
//getchar();
}
if (degree)
{
return 0;
}
//cout << "Acestor is " << id << endl;
return id;
}
int curLevel=0;
int parentID;
int level;
void ConstructAncestorMap(const int currentID)
{
level = 1;
parentID = matAncestors[0][currentID];
while ((1<<(level)) <= curLevel)
{
parentID = matAncestors[level-1][parentID];
matAncestors[level][currentID] = parentID;
matAncestorsSize[currentID]++;
level++;
}
curLevel++;
for (uint32 i=0; i<graph[currentID].size(); ++i)
{
matAncestors[0][graph[currentID][i]] = currentID;
matAncestorsSize[graph[currentID][i]] = 1;
ConstructAncestorMap(graph[currentID][i]);
}
curLevel--;
}
int main()
{
int n, m;
//AncestorMatrix matAncestors;
vector<int> vRoots;
fstream fin("stramosi.in", fstream::in);
fstream fout("stramosi.out", fstream::out);
fin >> n >> m;
//cout << n << " " << m << "\n";
graph.resize(n+1);
for (int i=1; i<=n; ++i)
{
int x;
fin >> x;
if (!x)
{
vRoots.push_back(i);
}
else
{
graph[x].push_back(i);
}
}
for (uint32 i=0; i<vRoots.size(); ++i)
{
// cout << vRoots[i] << " ";
ConstructAncestorMap(vRoots[i]);
}
//cout << "\n";
/*for (uint32 i=1; i<=n; ++i)
{
cout << i << "-> ";
for (uint32 j=0; j<graph[i].size(); ++j)
{
cout << graph[i][j] << " ";
}
cout << "\n";
}*/
/*int curQ = 0;
int curLevel = 0;
queue<int> Q[2];
for (uint32 i=0; i<vRoots.size(); ++i)
{
Q[curQ].push(vRoots[i]);
}
while (!Q[curQ].empty() || !Q[!curQ].empty())
{
while (!Q[curQ].empty())
{
int currentID = Q[curQ].front();
Q[curQ].pop();
int level = 1;
int parentID = matAncestors[0][currentID];
while ((1<<(level)) <= curLevel)
{
parentID = matAncestors[level-1][parentID];
matAncestors[level][currentID] = parentID;
matAncestorsSize[currentID]++;
level++;
}
for (uint32 i=0; i<graph[currentID].size(); ++i)
{
matAncestors[0][graph[currentID][i]] = currentID;
matAncestorsSize[graph[currentID][i]] = 1;
Q[!curQ].push(graph[currentID][i]);
}
}
curLevel++;
curQ = !curQ;
}*/
/*cout << "Size = " << matAncestors[13].size() << endl;
for (uint32 i=0; i<matAncestors[13].size(); ++i)
{
cout << matAncestors[13][i] << endl;
}*/
for (int i=0; i<m; ++i)
{
int p,q;
fin >> q >> p;
fout << Query(q, p) << "\n";
}
fin.close();
fout.close();
return 0;
}