poj 2774

最长公共子串

 

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#define maxn 100010 * 2
using namespace std;
int n, k;
int rank[maxn];
int tmp[maxn];
int sa[maxn], lcp[maxn];
string S,T;
bool compara_sa(int i, int j){
	if(rank[i] != rank[j]) return rank[i] < rank[j];
	else{
		int ri = i + k <= n ? rank[i + k] : -1;
		int rj = j + k <= n ? rank[j + k] : -1;
		return ri < rj;
	}
}

void construct_sa(string S, int *sa){
	n = S.length();
	for(int i = 0;i <= n;i++){
		sa[i] = i;
		rank[i] = i < n ? S[i] : -1;
	}
	
	for(k = 1;k <= n;k *= 2){
		sort(sa, sa + n + 1, compara_sa);
		tmp[sa[0]] = 0;
		for(int i = 1;i <= n;i++){
			tmp[sa[i]] = tmp[sa[i - 1]] + (compara_sa(sa[i - 1], sa[i]) ? 1 : 0);
		}
		for(int i = 0;i <= n;i++){
			rank[i] = tmp[i];
		}
	}
}

void construct_lcp(string S, int *sa, int *lcp){
	int n = S.length();
	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(;j + h < n&&i + h < n;h++){
			if(S[j + h] != S[i + h]) break;
		}
		
		lcp[rank[i] - 1] = h;
	}
}

void solve(){
	int s1 = S.length();
	S += '\0' + T;
	construct_sa(S, sa);
	construct_lcp(S, sa, lcp);
	int ans = 0;
	for(int i = 0;i < S.length();i++){
		if((sa[i] < s1) != (sa[i + 1] < s1)){
			ans = max(ans, lcp[i]);
		}
	}
	printf("%d\n", ans);
}

int main()
{
	while(cin>>S>>T)
		solve();
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值