Pagini recente » Cod sursa (job #1317866) | Cod sursa (job #1257655) | Cod sursa (job #2330924) | Cod sursa (job #2648766) | Cod sursa (job #2444698)
// stramosi.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
//#include "pch.h"
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <string>
#include <memory>
#include <cassert>
#define NMAX 100000
using namespace std;
using namespace std;
class Input_Reader {
private:
FILE *__inputFile;
long long fileSize, buffSize;
unique_ptr < char[] > buffer;
int Poz = 0;
inline long long min(const long long &a, const long long &b) { return a < b ? a : b; }
inline void CountBytes(const string &fileName) {
FILE * fin = fopen(fileName.c_str(), "r");
fseek(fin, 0, SEEK_END);
fileSize = ftell(fin);
fclose(fin);
}
inline bool isFigure(char x) {
return x >= '0' && x <= '9';
}
inline void JumpOver() {
while (!isFigure(buffer[Poz])) {
if (Poz + 1 == NMAX) {
fread(buffer.get(), sizeof(char), min(fileSize, NMAX), __inputFile), buffSize = strlen(buffer.get());
Poz = -1;
}
++Poz;
}
}
inline int Parse() {
int number = 0;
while (!isFigure(buffer[Poz]))JumpOver();
while (isFigure(buffer[Poz])) {
number = number * 10 + buffer[Poz] - '0';
++Poz;
if (Poz == NMAX)fread(buffer.get(), sizeof(char), min(fileSize, NMAX), __inputFile), buffSize = strlen(buffer.get()), Poz = 0;
}
return number;
}
public:
explicit Input_Reader(const string &str, const string &mode) {
__inputFile = fopen(str.c_str(), mode.c_str());
buffer = move(make_unique<char[]>(NMAX));
CountBytes(str);
fread(buffer.get(), sizeof(char), min(fileSize, NMAX), __inputFile);
buffSize = strlen(buffer.get());
}
Input_Reader &operator >> (int &value) {
value = Parse();
return *this;
}
};
class Solver {
public:
explicit Solver(string&& in, string&& out) {
FILE* fout = fopen(out.c_str(), "w");
Input_Reader fin{ in.c_str(), "r" };
int Q;
vector <int> ancestors;
// read data
fin >> N >> Q;
// resize the vector so that it have enough space for all numbers
ancestors.resize(N + 1);
for (int i = 1; i <= N; ++i) {
fin >> ancestors[i];
}
// do the dynamic programming magic :))
__process(ancestors);
// answer the questions
int P, X;
while (Q--) {
fin >> X >> P;
fprintf(fout, "%d\n", __solve(X, P));
}
}
private:
int __lg(int number) const {
return floor(log2(number));
}
void __process(const vector<int>& ancestors) {
// create the empty matrix
__intializeMatrix();
/*
S[i][j] = the 2 ^ j ancestor of node i
S[i][0] = ancestors[i]
S[i][j] = S[S[i][j-1]][j-1] while S[i][j - 1] != 0
*/
for (int i = 1; i <= N; ++i) {
// first ancestor is the father
S[i][0] = ancestors[i];
// calculate the second, the forth, ..., ancestor of node i as long as it exists
for (int j = 1; j <= __lg(N); ++j) {
if (!S[i][j - 1]) {
break;
}
S[i][j] = S[S[i][j - 1]][j - 1];
}
}
}
void __intializeMatrix() {
int log = __lg(N) + 1;
S.resize(N + 1);
for (int i = 1; i <= N; ++i) {
S[i].resize(log);
}
}
int __solve(int Q, int P) {
if (__lg(P) > __lg(N)) {
return 0;
}
// if P is power of 2 then the answer is calculated in the matrix
int value = __lg(P);
if ((1 << value) == P) {
return S[Q][value];
}
// calculate the nth ancestor
int power = __lg(P), ancestor;
for (; P != 0; power = __lg(P)) {
ancestor = S[Q][power];
if (!ancestor) {
break;
}
P -= (1 << power), Q = ancestor;
}
return ancestor;
}
int N;
vector <vector<int>> S;
} solver{
"stramosi.in",
"stramosi.out"
};
int main() {
return 0;
}