SPOJ 1811 Longest Common Substring拡張子自動機
8206 ワード
テンプレートソース:http://www.neroysq.com/?p=76
考え方:http://blog.sina.com.cn/s/blog_7812 e 9860012 dfv.
つまり、2つの文字列の最長の共通部分の列を求めて、最大25000文字列を連結します。
Aを直列にして拡張子のモチーフを構築し、Bを通してマッチングします。エニュメレート列Bの各ビットB[i]は、B[i]を終端とするすべてのサブストリングを考慮し、維持された値はB[i]を終端としてマッチングできる最大長tmpLとする。
B[i]に行くとストリングスにマッチしていますが、現在のノードにB[i]という息子がいたら、まっすぐ下に行ってください。
もしないなら、failポインタに沿って前に戻ります。息子がいるノードが見つかるまで。
考え方:http://blog.sina.com.cn/s/blog_7812 e 9860012 dfv.
つまり、2つの文字列の最長の共通部分の列を求めて、最大25000文字列を連結します。
Aを直列にして拡張子のモチーフを構築し、Bを通してマッチングします。エニュメレート列Bの各ビットB[i]は、B[i]を終端とするすべてのサブストリングを考慮し、維持された値はB[i]を終端としてマッチングできる最大長tmpLとする。
B[i]に行くとストリングスにマッチしていますが、現在のノードにB[i]という息子がいたら、まっすぐ下に行ってください。
もしないなら、failポインタに沿って前に戻ります。息子がいるノードが見つかるまで。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN = 250010;
const int SigmaSize = 26;
struct sanode
{
sanode *f, *ch[SigmaSize];
int l;
};
struct Suffix_Automaton
{
sanode pool[ ( MAXN << 1 ) + 20 ];
sanode *init;
sanode *tail;
int tot;
void Clear()
{
tot = 0;
init = pool;
tail = init;
return;
}
void Insert( int c )
{
sanode *q = pool + ( ++tot ), *p = tail;
q->l = p->l + 1;
for ( ; p && !p->ch[c]; p = p->f ) p->ch[c] = q;
tail = q;
if ( !p ) q->f = init;
else
{
if ( p->ch[c]->l == p->l + 1 ) q->f = p->ch[c];
else
{
sanode *r = pool + ( ++tot ), *u = p->ch[c];
*r = *u;
r->l = p->l + 1;
u->f = q->f = r;
for ( ; p && p->ch[c] == u; p = p->f ) p->ch[c] = r;
}
}
}
};
char str[MAXN + 20];
Suffix_Automaton SAM;
int main()
{
int len;
scanf( "%s", str + 1 );
SAM.Clear();
len = strlen( str + 1 );
for ( int i = 1; i <= len; ++i )
SAM.Insert( str[i] - 'a' );
sanode *p = SAM.init;
scanf( "%s", str + 1 );
len = strlen( str + 1 );
int tmpL = 0, ans = 0;
for ( int i = 1; i <= len; ++i )
{
if ( p->ch[ str[i] - 'a' ] ) //
p = p->ch[ str[i] - 'a' ], ++tmpL;
else // p str[i]
{
while ( p && !p->ch[ str[i] - 'a' ] )
p = p->f; // fail , str[i] ,
if( p ) // str[i]
{
tmpL = p->l + 1;
p = p->ch[ str[i] - 'a' ];
}
else //
{
p = SAM.init;
tmpL = 0;
}
}
ans = max( ans, tmpL );
}
printf( "%d
", ans );
return 0;
}