46 int const blocI = i / blocSize_;
48 int const blocJ = j / blocSize_;
52 std::array<int, 3> min_pos, min_value;
54 min_pos[0] = blocI * blocSize_
55 + normalizedBlocTable_[blocToNormalizedBloc_[blocI]]
56 [i % blocSize_][blocSize_ - 1];
58 min_pos[1] = ((blocJ - blocI) > 1)
59 ? blocMinimumPosition_[blocMinimumValueRMQ_.query(
60 blocI + 1, blocJ - 1)]
65 + normalizedBlocTable_[blocToNormalizedBloc_[blocJ]][0][j % blocSize_];
67 min_value[0] = nodeDepth_[min_pos[0]];
68 min_value[1] = (min_pos[1] != INT_MAX) ? nodeDepth_[min_pos[1]] : INT_MAX;
69 min_value[2] = nodeDepth_[min_pos[2]];
71 return min_pos[min_pos_3(min_value)];
74 return blocI * blocSize_
75 + normalizedBlocTable_[blocToNormalizedBloc_[blocI]][i % blocSize_]
82 int const sizeOfArray =
static_cast<int>(nodeDepth_.size());
83 blocSize_ =
static_cast<int>(log2(sizeOfArray) / 2.0);
84 int const numberOfBlocs
85 = sizeOfArray / blocSize_ + (sizeOfArray % blocSize_ != 0);
87 for(
int i = 0; i < numberOfBlocs; i++) {
88 std::pair<int, int> range;
89 range.first = i * blocSize_;
90 range.second = (i + 1) * blocSize_;
91 blocPartition_.push_back(range);
93 if(sizeOfArray % blocSize_ != 0) {
94 std::pair<int, int> range;
95 range.first = (numberOfBlocs - 1) * blocSize_;
96 range.second = sizeOfArray;
97 blocPartition_.push_back(range);
100 blocMinimumValue_.resize(numberOfBlocs);
101 blocMinimumPosition_.resize(numberOfBlocs);
102 for(
int i = 0; i < numberOfBlocs; i++) {
103 blocMinimumValue_[i] = nodeDepth_[blocPartition_[i].first];
104 blocMinimumPosition_[i] = blocPartition_[i].first;
105 for(
int j = blocPartition_[i].first + 1; j < blocPartition_[i].second;
107 if(nodeDepth_[j] < blocMinimumValue_[i]) {
108 blocMinimumValue_[i] = nodeDepth_[j];
109 blocMinimumPosition_[i] = j;
114 int const numberOfTables = (1 << (blocSize_ - 1));
115 normalizedBlocTable_.resize(numberOfTables);
116 for(
int i = 0; i < numberOfTables; i++) {
117 normalizedBlocTable_[i].resize(blocSize_);
118 for(
int j = 0; j < blocSize_; j++) {
119 normalizedBlocTable_[i][j].resize(blocSize_);
123 for(
int i = 0; i < numberOfTables; i++) {
125 std::vector<bool> plusOne(blocSize_ - 1);
128 for(
int j = 0; j < (blocSize_ - 1); j++) {
129 remain = quotient % 2;
131 plusOne[blocSize_ - 2 - j] =
static_cast<bool>(remain);
136 std::vector<int> normalizedBloc(blocSize_);
137 normalizedBloc[0] = 0;
138 for(
int j = 0; j < (blocSize_ - 1); j++) {
140 normalizedBloc[j + 1] = normalizedBloc[j] + 1;
142 normalizedBloc[j + 1] = normalizedBloc[j] - 1;
150 for(
int j = 0; j < blocSize_; j++) {
151 normalizedBlocTable_[i][j][j] = j;
152 for(
int k = j + 1; k < blocSize_; k++) {
153 normalizedBlocTable_[i][j][k] = rmq.
query(j, k);
154 normalizedBlocTable_[i][k][j] = normalizedBlocTable_[i][j][k];
159 blocToNormalizedBloc_.resize(numberOfBlocs, -1);
160 for(
int i = 0; i < numberOfBlocs; i++) {
163 for(
int j = blocPartition_[i].first + 1; j < blocPartition_[i].second;
165 if(nodeDepth_[j] > nodeDepth_[j - 1]) {
166 tableId += (1 << (blocSize_ - 2 - level));
170 blocToNormalizedBloc_[i] = tableId;
178 for(
unsigned int i = 0; i < getNumberOfNodes(); i++) {
179 if(node_[i].getAncestorId() ==
static_cast<int>(i)) {
185 this->printErr(
"Tree root not found.");
188 this->
printMsg(
"Rout found: node id = " + std::to_string(rootId),
191 if(!(node_[rootId].getNumberOfSuccessors() > 0)) {
192 this->printErr(
"Tree root found with no successor.");
197 nodeOrder_.reserve(2 * getNumberOfNodes() + 1);
199 nodeDepth_.reserve(2 * getNumberOfNodes() + 1);
200 nodeFirstAppearance_.clear();
201 nodeFirstAppearance_.resize(getNumberOfNodes(), -1);
203 std::stack<int> nodeStack;
206 std::vector<bool> isVisited(getNumberOfNodes(),
false);
207 nodeStack.push(rootId);
208 while(!nodeStack.empty()) {
209 int const nodeId = nodeStack.top();
211 nodeOrder_.push_back(nodeId);
212 nodeDepth_.push_back(depth);
213 if(!isVisited[nodeId]) {
215 if(nodeId != rootId) {
216 nodeStack.push(node_[nodeId].getAncestorId());
219 int const numberOfSuccessors = node_[nodeId].getNumberOfSuccessors();
220 for(
int i = 0; i < numberOfSuccessors; i++) {
221 nodeStack.push(node_[nodeId].getSuccessorId(i));
223 nodeFirstAppearance_[nodeId] = iteration;
224 isVisited[nodeId] =
true;
227 if(!nodeStack.empty()) {
228 if(nodeStack.top() == node_[nodeId].getAncestorId()) {