Pagini recente » Cod sursa (job #170536) | Cod sursa (job #1124266) | Cod sursa (job #180683) | Cod sursa (job #2651642) | Cod sursa (job #2096733)
#include <bits/stdc++.h>
using namespace std;
const int maxWords = 1e4+5,
maxLetters = 2e5+5,
sigma = 26,
dimensions = 2,
layers = 18;
struct Trie{
private:
static int contor;
public:
int finished, length, signature;
Trie *child[sigma];
Trie (){
finished = 0;
length = 0;
for ( int index = 0; index < sigma; index++ )
this->child[index] = NULL;
signature = contor;
contor++;
}
inline void addWord(string word, int &location);
};
int Trie :: contor = 0;
Trie dictionary;
inline void Trie :: addWord(string word, int &location){
int lengthWord = word.length();
Trie *position = &dictionary;
int letter;
for ( int index = 0; index < lengthWord; index++ ){
letter = word[index]-'a';
if ( position->child[letter] == NULL ){
position->child[letter] = new Trie;
position->child[letter]->length = position->length+1;
}
position = position->child[letter];
if ( index == lengthWord-1 ){
position->finished++;
location = position->signature;
}
}
}
ifstream fin ("ratina.in");
ofstream fout ("ratina.out");
vector <int> eulerChart;
int totalWords, totalQuestions,
depth;
int positions[maxWords],
eulerPositions[maxWords*2],
level[maxLetters*2],
lengthLayer[layers],
lg2[maxLetters*2];
int rangeMinimumQuery[dimensions][layers][maxLetters];
inline void readVaribles(){
string word;
fin >> totalWords >> totalQuestions;
for ( int index = 0; index < totalWords; index++ ){
fin >> word;
dictionary.addWord(word, positions[index]);
}
}
void depthFirstSearch(Trie *location = &dictionary){
eulerChart.push_back(location->signature);
eulerPositions[location->signature] = eulerChart.size();
level[location->signature] = location->length;
for ( int index = 0; index < sigma; index++ ){
if ( location->child[index] ){
depthFirstSearch(location->child[index]);
eulerChart.push_back(location->signature);
}
}
}
inline void calculateAncenstors(){
lengthLayer[0] = eulerChart.size();
depth = lg2[lengthLayer[0]];
for ( int index = 1; index <= lengthLayer[0]; index++ ){
rangeMinimumQuery[0][0][index] = level[eulerChart[index-1]];
rangeMinimumQuery[1][0][index] = eulerChart[index-1];
}
for ( int index = 1; index <= depth; index++ ){
lengthLayer[index] = lengthLayer[index-1] - (1<<(index-1));
}
for ( int indexY = 1; indexY <= depth; indexY++ ){
for ( int indexX = 1; indexX <= lengthLayer[indexY]; indexX++ ){
if ( rangeMinimumQuery[0][indexY-1][indexX] < rangeMinimumQuery[0][indexY-1][indexX + (1<<(indexY-1))] ){
rangeMinimumQuery[0][indexY][indexX] = rangeMinimumQuery[0][indexY-1][indexX];
rangeMinimumQuery[1][indexY][indexX] = rangeMinimumQuery[1][indexY-1][indexX];
}
else{
rangeMinimumQuery[0][indexY][indexX] = rangeMinimumQuery[0][indexY-1][indexX + (1<<(indexY-1))];
rangeMinimumQuery[1][indexY][indexX] = rangeMinimumQuery[1][indexY-1][indexX + (1<<(indexY-1))];
}
}
}
}
int answerQuestion(int first, int second){
int positionFirst = eulerPositions[positions[first-1]],
positionSecond = eulerPositions[positions[second-1]];
if ( positionFirst > positionSecond )
swap(positionFirst, positionSecond);
int lengthPeriod = positionSecond - positionFirst + 1;
int maxPeriod = 1 << lg2[lengthPeriod];
int indexY = lg2[maxPeriod];
if ( rangeMinimumQuery[0][indexY][positionFirst] < rangeMinimumQuery[0][indexY][positionSecond-(1<<indexY)+1])
return rangeMinimumQuery[0][indexY][positionFirst];
else
return rangeMinimumQuery[0][indexY][positionSecond-(1<<indexY)+1];
}
inline void readQuestions(){
int totalElements,
first, second,
answer;
for ( ; totalQuestions; totalQuestions-- ){
answer = 1<<30;
fin >> totalElements >> first;
for ( int index = 1; index < totalElements; index++ ){
fin >> second;
answer = min(answer, answerQuestion(first, second));
first = second;
}
fout << answer << "\n";
}
}
inline void calculateLog2(){
for ( int index = 2; index <= eulerChart.size(); index++ )
lg2[index] = lg2[index >> 1] + 1;
}
inline void debbugingPurposes(){
cout << "\n";
for ( int index = 1; index <= totalWords; index++ )
cout << positions[index-1] << " ";
cout << "\n";
for ( int index = 1; index <= totalWords; index++ )
cout << eulerPositions[index-1] << " ";
cout << "\n\n!";
}
int main(){
readVaribles();
depthFirstSearch();
calculateLog2();
calculateAncenstors();
readQuestions();
}