Longest Common Substring HDU - 1403后缀数组

Given two strings, you have to tell the length of the Longest Common Substring of them.

For example:
str1 = banana
str2 = cianaic

So the Longest Common Substring is "ana", and the length is 3.

InputThe input contains several test cases. Each test case contains two strings, each string will have at most 100000 characters. All the characters are in lower-case.

Process to the end of file.
OutputFor each test case, you have to tell the length of the Longest Common Substring of them.
Sample Input

banana
cianaic

Sample Output

3
#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<iomanip>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
const int mx = 200005; //check the limits, dummy
typedef pair<int, int> pa;
const double PI = acos(-1);
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
bool isprime(int n) { if (n <= 1)return 0; for (int i = 2; i * i <= n; i++)if (n % i == 0)return 0; return 1; }
#define swa(a,b) a^=b^=a^=b
#define re(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define rb(i,a,b) for(ll i=(a),_=(b);i>=_;i--)
#define clr(a,b) memset(a, b, sizeof(a))
#define lowbit(x) ((x)&(x-1))
#define mkp make_pair
//inline ll qpow(ll a, ll b) { return b ? ((b & 1) ? a * qpow(a * a % mod, b >> 1) % mod : qpow(a * a % mod, b >> 1)) % mod : 1; }
//inline ll qpow(ll a, ll b, ll c) { return b ? ((b & 1) ? a * qpow(a * a % c, b >> 1) % c : qpow(a * a % c, b >> 1)) % c : 1; }
void ca(int kase, int ans) { cout << "Case #" << kase << ": " << ans << endl; }
void sc(int& x) { scanf("%d", &x); }void sc(int64_t& x) { scanf("%lld", &x); }void sc(double& x) { scanf("%lf", &x); }void sc(char& x) { scanf(" %c", &x); }void sc(char* x) { scanf("%s", x); }
int n,  t, k;
char s[mx];
int sa[mx], cnt[mx], t1[mx], t2[mx], rk[mx], height[mx];
void cal_sa() {
    int m = 127;
    int i, * x = t1, * y = t2;
    re(i, 0, m)cnt[i] = 0;
    re(i, 0, n)cnt[x[i] = s[i]]++;
    re(i, 1, m)cnt[i] += cnt[i - 1];
    for (int i = n - 1; i >= 0; i--)sa[--cnt[x[i]]] = i;
    for (int k = 1; k <= n; k << 1) {
        int p = 0;
        re(i, n - k, n)y[p++] = i;
        re(i, 0, n)if (sa[i] >= k)y[p++] = sa[i] - k;
        re(i, 0, m)cnt[i] = 0;
        re(i, 0, n)cnt[x[y[i]]]++;
        re(i, 1, m)cnt[i] += cnt[i - 1];
        for (int i = n - 1; i >= 0; i--)sa[--cnt[x[y[i]]]] = y[i];
        swap(x, y);
        p = 1; x[sa[0]] = 0;
        re(i, 1, n)x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
        if (p >= n)break;
        m = p;
    }
}
void getheight(int) {
    int i, j, k = 0;
    re(i, 0, n)rk[sa[i]] = i;
    re(i, 0, n) {
        if (k)k--;
        j = sa[rk[i] - 1];
        while (s[i + k] == s[j + k])k++;
        height[rk[i]] = k;
    }
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int len1, ans;
    while (scanf("%s",s)!=EOF) {
        n = strlen(s);
        len1 = n;
        s[n] = '$';
        scanf("%s", s + n + 1);
        n = strlen(s);
        cal_sa();
        getheight(n);
        ans = 0;
        re(i, 1, n)
            if (height[i] > ans &&
                ((sa[i - 1] < len1 && sa[i] >= len1) || (sa[i - 1] >= len1 && sa[i] < len1)))
                ans = height[i];
        cout << ans << endl;
    }
    return 0;
}

 

posted @ 2020-05-14 16:36  XXXSANS  阅读(135)  评论(0编辑  收藏  举报