POJ 2217 (字尾陣列+LCP)
阿新 • • 發佈:2019-01-07
要注意最後的空串也要算進去,所以是<=n
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#define LL long long
#define eps 1e-8
const LL INF = 0x3f3f3f3f;
const int maxn = 200000 + 5;
using namespace std;
int sa[maxn*2];
int t[maxn*2];
int t2[maxn*2];
int c[maxn*2];
int Rank[maxn];
int lcp[maxn];
string s1, s2;
void get_lcp(int n, string s){
int i,j,k = 0;
for(i=0; i<=n; i++) Rank[sa[i]] = i;
for(i=0; i<n; i++){
if(k) k--;
j = sa[Rank[i]-1];
while (s[i+k] == s[j+k]) k++;
lcp[Rank[i]-1] = k;
}
}
void build_sa(int n, int m, string s){
int *x = t, *y = t2;
n++;
for(int i=0; i<m; i++) c[i] = 0;
for(int i=0; i<n; i++) c[x[i] = s[i]]++;
for(int i=1; i<m; i++) c[i] += c[i-1];
for(int i=n-1; i>=0; i--) sa[--c[x[i]]] = i;
for (int k=1; k<=n; k<<=1){
int p = 0;
for(int i=n-k; i<n; i++) y[p++] = i;
for(int i=0; i<n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(int i=0; i<m; i++) c[i] = 0;
for(int i=0; i<n; i++) c[x[y[i]]]++;
for(int i=0; i<m; i++) c[i] += c[i-1];
for(int i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x,y);
p = 1; x[sa[0]] = 0;
for(int i=1; i<n; i++)
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;
}
}
int main(){
int T;
scanf("%d",&T);
getchar();
while(T--){
getline(cin,s1);
getline(cin,s2);
int len = (int)s1.length();
s1 += '#' + s2;
int n = (int)s1.length();
build_sa(n,300,s1);
get_lcp(n,s1);
int ans = 0;
for(int i=0; i<n; i++){
if((sa[i] < len) != (sa[i+1] < len)){
ans = max(ans, lcp[i]);
}
}
printf("Nejdelsi spolecny retezec ma delku %d.\n",ans);
}
}