记录编号 491123 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [POI 2000] 最长公共子串 最终得分 100
用户昵称 Gravatar胡嘉兴 是否通过 通过
代码语言 C++ 运行时间 4.022 s
提交时间 2018-03-14 20:04:40 内存使用 6.71 MiB
显示代码纯文本
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+7, inf = 1e9;
int n, m = 127;
char s[N];
vector<int> vec;
int sa[N], tp[N], tax[N], rak[N], book[N], height[N], st[N][20];
void pr(int* a, int n)
{
    for(int i = 1; i <= n; i++)
    {
        printf("%d ", a[i]);
    }
    puts("");
}
void distribution_sort()
{
    for(int i = 0; i <= m; i++)
    {
        tax[i] = 0;
    }
    for(int i = 1; i <= n; i++)
    {
        tax[rak[i]]++;
    }
    for(int i = 1; i <= m; i++)
    {
        tax[i] += tax[i-1];
    }
    for(int i = n; i >= 1; i--)
    {
        sa[tax[rak[tp[i]]]--] = tp[i];
    }
    return;
}
void SA()
{
    for(int i = 1; i <= n; i++)
    {
        tp[i] = i;
        rak[i] = s[i];
    }
    distribution_sort();
    for(int k = 1, p = 1; k <= n&&p < n; k <<= 1, m = p)
    {
        p = 0;
        for(int i = 1; i <= k; i++)
        {
            tp[++p] = n-k+i;
        }
        for(int i = 1; i <= n; i++)
        {
            if(sa[i]>k)
            {
                tp[++p] = sa[i]-k;
            }
        }
        distribution_sort();
        swap(rak, tp);
        rak[sa[1]] = p = 1;
        for(int i = 2; i <= n; i++)
        {
            rak[sa[i]] = (tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+k]==tp[sa[i]+k]) ? p : ++p;
        }
    }
    return;
}
void get_height()
{
    int k = 0;
    for(int i = 1; i <= n; i++)
    {
        rak[sa[i]] = i;
    }
    for(int i = 1; i <= n; i++)
    {
        if(rak[i]==1)
        {
            continue;
        }
        if(k)
        {
            k--;
        }
        int j = sa[rak[i]-1];
        while(j+k<=n&&i+k<=n&&s[i+k]==s[j+k]&&book[i]==book[i+k]&&book[j]==book[j+k])
        {
            k++;
        }
        height[rak[i]] = k;
    }
    return;
}
int query(int l, int r)
{
    if(l>r)
    {
        swap(l, r);
    }
    l++;
    int k = 0, ret;
    while((1<<(k+1))<=r-l+1)
    {
        k++;
    }
    return min(st[l][k], st[r-(1<<k)+1][k]);
}
int main()
{
    int t, ans = 0;
    freopen("pow.in","r",stdin);
    freopen("pow.out","w",stdout);
    scanf("%d", &t);
    vec.push_back(0);
    for(int i = 0; i < t; i++)
    {
        scanf("%s", s+1+n);
        int tmp = strlen(s+1);
        for(int j = n+1; j <= tmp; j++)
        {
            book[j] = tmp;
        }
        n = tmp;
        vec.push_back(n);
    }
	SA();
	get_height();
	for(int i = 1; i <= n; i++)
    {
        st[i][0] = height[i];
    }
    for(int j = 1; (1<<j) <= n; j++)
    {
        for(int i = 1; i + (1<<j) <= n; i++)
        {
            st[i][j] = min(st[i][j-1], st[i+(1<<(j-1))][j-1]);
        }
    }
    for(int i = 1; i <= vec[1]; i++)
    {
        int cnt = inf;
        for(int j = 2; j < vec.size(); j++)
        {
            int cur = 0;
            for(int k = vec[j-1]+1; k <= vec[j]; k++)
            {
                cur = max(cur, query(rak[i], rak[k]));
            }
            cnt = min(cnt, cur);
        }
        ans = max(ans, cnt);
    }
    printf("%d\n", ans);
	return 0;
}