Pagini recente » Cod sursa (job #1211230) | Cod sursa (job #1598675) | Cod sursa (job #1003300) | Cod sursa (job #2803407) | Cod sursa (job #883422)
Cod sursa(job #883422)
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <map>
using namespace std;
class SuffixAutomaton {
public:
class element {
public:
element(const int &_length = 0, const int &_link = -1, const int &_endings = 0) {
length = _length;
link = _link;
endings = _endings;
solved = false;
}
int length;
int link;
int endings;
map<char, int> edges;
bool solved;
};
SuffixAutomaton(const string &S = "") {
nodes.push_back(element());
lastNode = 0;
for (string::const_iterator c = S.begin(); c != S.end(); ++c)
extend(*c);
}
int getLongestKTimes(const int &K) {
for (int i = lastNode; i != -1; i = nodes[i].link)
nodes[i].endings = 1;
getAnswer(0);
int best = 0;
for (vector<element>::iterator it = nodes.begin(); it != nodes.end(); ++it)
if (it -> endings >= K)
best = max(best, it -> length);
//for (int i = 0; i < int(nodes.size()); ++i) {
// cerr << i << " -> length(" << nodes[i].length << ") link(" << nodes[i].link << ") endings(" << nodes[i].endings << ") edges -> ";
// for (map<char, int>::iterator it = nodes[i].edges.begin(); it != nodes[i].edges.end(); ++it)
// cerr << "(" << it -> first << " -> " << it -> second << ") ";
// cerr << "\n";
//}
return best;
}
private:
void extend(char c) {
int now = nodes.size();
nodes.push_back(element(nodes[lastNode].length + 1));
int k;
for (k = lastNode; k != -1 && !nodes[k].edges.count(c); k = nodes[k].link)
nodes[k].edges[c] = now;
lastNode = now;
if (k == -1) {
nodes[now].link = 0;
return;
}
int next = nodes[k].edges[c];
if (nodes[k].length + 1 == nodes[next].length) {
nodes[now].link = next;
return;
}
// we don't have a possible link, so we clone the node that should follow k
int clone = nodes.size();
nodes.push_back(element(nodes[k].length + 1, nodes[next].link));
nodes[clone].edges = nodes[next].edges;
for (; k != -1 && nodes[k].edges[c] == next; k = nodes[k].link)
nodes[k].edges[c] = clone;
nodes[next].link = nodes[now].link = clone;
}
int getAnswer(int nod) {
if (nodes[nod].solved)
return nodes[nod].endings;
for (map<char, int>::iterator it = nodes[nod].edges.begin(); it != nodes[nod].edges.end(); ++it)
nodes[nod].endings += getAnswer(it -> second);
nodes[nod].solved = true;
return nodes[nod].endings;
}
vector<element> nodes;
int lastNode;
};
int main() {
ifstream cin("substr.in");
ofstream cout("substr.out");
int N, K; cin >> N >> K;
string S; cin >> S;
SuffixAutomaton T(S);
cout << T.getLongestKTimes(K) << "\n";
}