Pagini recente » Cod sursa (job #2051935) | Cod sursa (job #2139005) | Cod sursa (job #2638353) | Cod sursa (job #2081274) | Cod sursa (job #2538020)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cassert>
using namespace std;
const int LOG = 15, N = 17000;
namespace SuffixArray {
int calc[LOG][N];
int sa[N], ord[N], lcp[N];///suficsii sortati, pozitia in vectorul sortat
int n, logn;
pair < pair < int, int >, int > aux[N];/// < < prima, a doua >, pozitie >
string s;
void Build(string _s) {
s = _s;
n = s.size();
assert(n != 1);
for (int i = 0; i < n; ++i)
calc[0][i] = s[i];
for (int k = 1; (1<<(k - 1)) < n; ++k) {
logn = k;///imi e prea lene sa fac separat
for (int i = 0; i < n; ++i)
aux[i] = {{calc[k - 1][i], (i + (1<<(k - 1)) < n ? calc[k - 1][i + (1<<(k - 1))] : -1)}, i};
sort(aux, aux + n);///daca nu intra in timp o sa fac counting sort
for (int i = 0; i < n; ++i)
calc[k][aux[i].second] = i;
}
for (int i = 0; i < n; ++i)
sa[calc[logn][i]] = i, ord[i] = calc[logn][i];
}
void Kasai() {
for (int k = 0, i = 0; i < n; ++i, k?k--:0) {
if (ord[i] == n - 1) {
k = 0;
continue;
}
int j = sa[ord[i] + 1];
while (i + k < n && j + k < n && s[i + k] == s[j + k])
k++;
lcp[ord[i]] = k;
}
}
}
using namespace SuffixArray;
int stk[N];
int v[N], stanga[N], dreapta[N];
int main()
{
ifstream fin("substr.in");
ofstream fout("substr.out");
int n, k;
string s;
fin >> n >> k >> s;
if (n == 1)
return fout << 1, 0;
Build(s);
Kasai();
// for (int i = 0; i < n; ++i)
// fout << sa[i] << ' ';
// fout << '\n';
// for (int i = 0; i < n; ++i)
// fout << ord[i] << ' ';
// fout << '\n';
// for (int i = 0; i < n; ++i)
// fout << lcp[i] << ' ';
// fout << '\n';
k--;
n--;
for (int i = 1; i <= n; ++i)
v[i] = lcp[i - 1];
///bagam skyline
int top(0);
v[0] = v[n + 1] = 0;
stk[++top] = 0;
for (int i = 1; i <= n; ++i) {
while (top && v[stk[top]] > v[i])
--top;
stanga[i] = stk[top];
stk[++top] = i;
}
top = 0;
stk[++top] = n + 1;
for (int i = n; i >= 1; --i) {
while (top && v[stk[top]] >= v[i])
--top;
dreapta[i] = stk[top];
stk[++top] = i;
}
int ans(0);
for (int i = 1; i <= n; ++i) {
if (v[stanga[i]] == v[i])
continue;
if (dreapta[i] - stanga[i] - 1 >= k)
ans += v[i] - max(v[stanga[i]], v[dreapta[i]]);
}
fout << ans;
return 0;
}