1.Problem
3415 -- Common Substrings (poj.org)
2.Idea
Suffix Array
Monotonic Stack
3.Source
const int MAX_L = 100000 + 1;
const int MAX_N = 2 * MAX_L + 1;
std::string S;
int n, k;
int sa[MAX_N + 1], lcp[MAX_N + 1];
int Rank[MAX_N + 1], tmp[MAX_N + 1];
bool compare_sa(const int i, const int j)
{
if (Rank[i] != Rank[j])
{
return Rank[i] < Rank[j];
}
return (i + k <= n ? Rank[i + k] : -1) < (j + k <= n ? Rank[j + k] : -1);
}
void construct_sa()
{
for (int i = 0; i <= n; i++)
{
sa[i] = i;
Rank[i] = i < n ? S[i] : -1;
}
for (k = 1; k <= n; k <<= 1)
{
std::sort(sa, sa + n + 1, compare_sa);
tmp[sa[0]] = 0;
for (int i = 1; i <= n; i++)
{
tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
}
for (int i = 0; i <= n; i++)
{
Rank[i] = tmp[i];
}
}
}
void construct_lcp()
{
memset(lcp, 0, sizeof(lcp));
for (int i = 0; i <= n; i++)
{
Rank[sa[i]] = i;
}
int h = 0;
lcp[0] = 0;
for (int i = 0; i < n; i++)
{
int j = sa[Rank[i] - 1];
if (h > 0)
{
h--;
}
for (; i + h < n && j + h < n && S[i + h] == S[j + h]; h++);
lcp[Rank[i] - 1] = h;
}
}
int Stack[MAX_N][2];
long long contribution, top;
using namespace std;
long long calc(int K, int l1, bool is_s1)
{
long long ans = 0;
for (int i = 0; i < n; i++) {
if (lcp[i] < K) {
top = contribution = 0;
}
else {
int size = 0;
if ((is_s1 && sa[i] < l1) || (!is_s1 && sa[i] > l1)) {
++size;
contribution += lcp[i] - K + 1;
}
while (top > 0 && lcp[i] <= Stack[top - 1][0]) {
--top;
contribution -= Stack[top][1] * (Stack[top][0] - lcp[i]);
size += Stack[top][1];
}
if (size) {
Stack[top][0] = lcp[i];
Stack[top][1] = size;
++top;
}
if ((is_s1 && sa[i + 1] > l1) || (!is_s1 && sa[i + 1] < l1)) {
ans += contribution;
}
}
}
return ans;
}
void solve()
{
int k;
while (scanf("%d", &k), k) {
string s1, s2;
cin >> s1 >> s2;
int l1 = s1.length();
int l2 = s2.length();
S = s1 + "$" + s2;
n = l1 + l2 + 1;
construct_sa();
construct_lcp();
printf("%lld\n", calc(k, l1, true) + calc(k, l1, false));
}
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(13);
solve();
return 0;
}
No comments:
Post a Comment