Pagini recente » Cod sursa (job #2715630) | Cod sursa (job #1293234) | Cod sursa (job #2417409) | Cod sursa (job #3281027) | Cod sursa (job #995665)
Cod sursa(job #995665)
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
class SuffixAutomaton {
public:
class Node {
public:
static const int NIL = -1;
int length, link, endings;
map<char, int> edges;
bool solved;
Node(const int length = 0, const int link = NIL) {
this->length = length;
this->link = link;
this->edges = map<char, int>();
this->endings = 0;
this->solved = false;
}
};
SuffixAutomaton(const string word = "") {
nodes.push_back(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 GetLongestKMatches(const int k) const {
int length = 0;
for (int x = 0; x < int(nodes.size()); ++x)
if (nodes[x].endings >= k)
length = max(length, nodes[x].length);
return length;
}
private:
int lastNode;
vector<Node> nodes;
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;
}
int GetEndings(const int x) {
if (nodes[x].solved)
return nodes[x].endings;
for (const auto &y: nodes[x].edges)
nodes[x].endings += GetEndings(y.second);
nodes[x].solved = true;
return nodes[x].endings;
}
};
string S;
int K, Solution;
void Solve() {
SuffixAutomaton T = SuffixAutomaton(S);
T.Preprocess();
Solution = T.GetLongestKMatches(K);
}
void Read() {
ifstream cin("substr.in");
int n;
cin >> n >> K >> S;
cin.close();
}
void Print() {
ofstream cout("substr.out");
cout << Solution << "\n";
cout.close();
}
int main() {
Read();
Solve();
Print();
return 0;
}