Pagini recente » Diferente pentru numerele-sprague-grundy intre reviziile 28 si 29 | Monitorul de evaluare | Cod sursa (job #1766040) | Cod sursa (job #453089) | Cod sursa (job #1165098)
#include <fstream>
#include <vector>
#include <map>
using namespace std;
class SuffixAutomaton {
public:
SuffixAutomaton(const string &word = ""):
nodes(vector<Node>(1, Node())),
lastNode(0) {
for (int i = 0; i < int(word.length()); ++i)
Extend(word[i]);
}
void Preprocess() {
for (int x = lastNode; x != Node::NIL; x = nodes[x].link)
nodes[x].endings = 1;
GetEndings(0);
}
int GetFrequence(const string &pattern) {
int x = 0;
for (int i = 0; i < int(pattern.length()); ++i) {
if (nodes[x].edges.count(pattern[i]) == 0)
return 0;
x = nodes[x].edges[pattern[i]];
}
return nodes[x].endings;
}
private:
class Node {
public:
static const int NIL = -1;
int length, link;
map<char, int> edges;
int endings;
bool solved;
Node(const int _length = 0, const int _link = NIL):
length(_length),
link(_link),
edges(map<char, int>()),
endings(0),
solved(false) {}
};
vector<Node> nodes;
int lastNode;
void Extend(const char symbol) {
int current = int(nodes.size());
nodes.push_back(Node(nodes[lastNode].length + 1));
int x = lastNode;
for (; x != Node::NIL && nodes[x].edges.count(symbol) == 0; x = nodes[x].link)
nodes[x].edges[symbol] = current;
lastNode = current;
if (x == Node::NIL) {
nodes[current].link = 0;
return;
}
int next = nodes[x].edges[symbol];
if (nodes[x].length + 1 == nodes[next].length) {
nodes[current].link = next;
return;
}
int clone = int(nodes.size());
nodes.push_back(Node(nodes[x].length + 1, nodes[next].link));
nodes[clone].edges = nodes[next].edges;
for (; x != Node::NIL && nodes[x].edges[symbol] == next; x = nodes[x].link)
nodes[x].edges[symbol] = clone;
nodes[current].link = nodes[next].link = clone;
}
void GetEndings(const int x) {
nodes[x].solved = true;
for (map<char, int>::const_iterator e = nodes[x].edges.begin(); e != nodes[x].edges.end(); ++e) {
if (!nodes[e->second].solved)
GetEndings(e->second);
nodes[x].endings += nodes[e->second].endings;
}
}
};
int main() {
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
string word;
cin >> word;
SuffixAutomaton automaton = SuffixAutomaton(word);
automaton.Preprocess();
int q;
cin >> q;
for (; q > 0; --q) {
string pattern;
cin >> pattern;
cout << automaton.GetFrequence(pattern) << "\n";
}
cin.close();
cout.close();
return 0;
}