spoj 1811 Longest Common Substring (后缀自动机)
来源:互联网 发布:php array shift函数 编辑:程序博客网 时间:2024/05/02 01:16
spoj 1811 Longest Common Substring (后缀自动机)
题意:lcs。。求两个字符串的最长公共连续子串
解题思路:后缀自动机解法。对第一个字符串构造sam,将第二个字符串的字符依次加入sam去匹配。假如我们匹配s2[i]时,匹配到的最大值为temp,在sam上匹配到的位置为p,那当加入s2[i+1]时应该如何更新呢?显然,如果p有指向s2[i]的儿子,temp[i+1] = temp[i] +1,p更新为p->son[k]。如果没有,那么p就沿着fa走,直到p有指向s2[i+1]的儿子,或者p走到NULL。假如p走到了NULL,那么在s2[i+1]这个位置,我们没有匹配到任何字符,故temp[i+1] = 0 , p 走到root。否则,temp[i+1] = val[p] + 1,p更新为p->son[k]。这里temp[i+1]是不能更新为val[q]的(设q=p->son[k]),因为val[q] 并不一定等于val[p] +1,而s2[i]我们只能匹配到p(p沿着fa走,那么很显然,这一路过来的p都能与s2[i]匹配)。
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std ;const int maxn = 250010 ;struct sam {int fa[maxn<<1] , c[26][maxn<<1] , val[maxn<<1] ;int dp[maxn<<1] , tot , last ;inline int new_node ( int step ) {int i ;val[++tot] = step ;fa[tot] = 0 ;for ( i = 0 ; i < 26 ; i ++ ) c[i][tot] = 0 ;return tot ;}void add ( int k ) {int i , p = last ;int np = new_node ( val[p] + 1 ) ;while ( p && !c[k][p] ) c[k][p] = np , p = fa[p] ;if ( !p ) fa[np] = 1 ;else {int q = c[k][p] ;if ( val[p] + 1 == val[q] ) fa[np] = q ;else {int nq = new_node ( val[p] + 1 ) ;for ( i = 0 ; i < 26 ; i ++ )c[i][nq] = c[i][q] ;fa[nq] = fa[q] ;fa[q] = fa[np] = nq ;while ( p && c[k][p] == q ) c[k][p] = nq , p = fa[p] ;}}last = np ;}void build ( char *s , int len ) {tot = 0 ;last = new_node ( 0 ) ;int i ;for ( i = 0 ; i < len ; i ++ )add ( s[i] - 'a' ) ;}int solve ( char *s ) {int len = strlen ( s ) , i ;int ret = 0 , pre = 0 ;int p = 1 ;memset ( dp , 0 , sizeof ( dp ) ) ;for ( i = 0 ; i < len ; i ++ ) {int k = s[i] - 'a' ;if ( c[k][p] ) pre ++ , p = c[k][p] ;else {while ( !c[k][p] && p ) p = fa[p] ;if ( p ) pre = val[p] + 1 , p = c[k][p] ;else p = 1 , pre = 0 ;}ret = max ( ret , pre ) ;}return ret ;}} suf ;char s[maxn] ;int main () {while ( scanf ( "%s" , s ) != EOF ) {suf.build ( s , strlen ( s ) ) ;scanf ( "%s" , s ) ;printf ( "%d\n" , suf.solve ( s ) ) ;}return 0 ;}
- spoj 1811 Longest Common Substring (后缀自动机)
- SPOJ-1811 Longest Common Substring(后缀自动机)
- SPOJ LCS Longest Common Substring 后缀自动机
- [SPOJ LCS]Longest Common Substring && 后缀自动机
- 【后缀自动机】[SPOJ LCS]Longest Common Substring
- SPOJ 1811 Longest Common Substring(后缀自动机)
- spoj 1811 Longest Common Substring (第一道后缀自动机)
- spoj 1811 LCS - Longest Common Substring (后缀自动机)
- spoj 1811 Longest Common Substring(后缀自动机)
- [后缀自动机 模板题] SPOJ 1811Longest Common Substring
- SPOJ 1812. Longest Common Substring II(后缀自动机)
- SPOJ LCS2 Longest Common Substring II 后缀自动机
- 【后缀自动机】[SPOJ LCS2]Longest Common Substring II
- spoj 1812 LCS2 - Longest Common Substring II (后缀自动机)
- SPOJ lcs2 Longest Common Substring II 后缀自动机
- spoj 1812 Longest Common Substring II(后缀自动机)
- SPOJ 1812 LCS2 - Longest Common Substring II (后缀自动机)
- 【后缀自动机】SPOJ(LCS)[Longest Common Substring]题解
- N-Queens
- IE 和FF chrome css不兼容问题小结(1)
- scala里面的for...yield循环
- 互联网计费模式
- 【安博培训技术】Oracle7 子程序和程序包20130912
- spoj 1811 Longest Common Substring (后缀自动机)
- ObjectC中弥补switch参数不能为字符串的方法(主要通过block特性)
- C语言指针和数组知识总结(上)
- linux-0.11抠代码-bootsect
- mysql数据库优化21条
- c++与js脚本交互,C++调用JS函数/JS调用C++函数
- vs调试技巧
- IOCP+WinSock2新函数打造高性能SOCKET池
- 【工具】show_space