kmp:
int nxt[ 100005 ] ;
char s[ 100005 ] , t[ 100005 ] ;
void kmp_next ( char * T, int * nt) {
nt[ 0 ] = - 1 ;
for ( int i= 0 , j= - 1 , m= strlen ( T) ; i< m; ) {
if ( j== - 1 || T[ i] == T[ j] ) {
i++ , j++ ;
if ( T[ i] != T[ j] ) nt[ i] = j;
else nt[ i] = nt[ j] ;
}
else j= nt[ j] ;
}
}
int kmp ( char * S, char * T, int * nt) {
kmp_next ( T, nt) ;
int ans= 0 , sn= strlen ( S) , tn= strlen ( T) ;
for ( int i= 0 , j= 0 ; i< sn; ) {
if ( j== - 1 || S[ i] == T[ j] ) i++ , j++ ;
else j= nt[ j] ;
if ( j== tn) ans++ ;
}
return ans;
}
字典树:
int tree[ maxn] [ 30 ] ;
int tsize[ maxn] ;
int tot;
void add_edge ( char * s) {
int len= strlen ( s) ;
int rt= 0 ;
for ( int i= 0 ; i< len; i++ ) {
int xb= s[ i] - 'a' ;
if ( ! tree[ rt] [ xb] ) tree[ rt] [ xb] = ++ tot;
tsize[ tree[ rt] [ xb] ] ++ ;
rt= tree[ rt] [ xb] ;
}
}
int query ( char * s) {
int len= strlen ( s) ;
int rt= 0 ;
for ( int i= 0 ; i< len; i++ ) {
int xb= s[ i] - 'a' ;
if ( ! tree[ rt] [ xb] ) return 0 ;
rt= tree[ rt] [ xb] ;
}
return tsize[ rt] ;
}
AC自动机:
struct Tire{
static const int NODENUM= ( int ) 1e6 + 5 , R= 26 ;
int nxt[ NODENUM] [ R] , fail[ NODENUM] , ed[ NODENUM] ;
int rt, tot;
int newnode ( ) {
for ( int i= 0 ; i< R; i++ ) nxt[ tot] [ i] = - 1 ;
ed[ tot] = 0 ;
return tot++ ;
}
void init ( ) {
tot= 0 ;
rt= newnode ( ) ;
}
void insert ( char * s) {
int now= rt, len= strlen ( s) ;
for ( int i= 0 ; i< len; i++ ) {
int val= s[ i] - 'a' ;
if ( nxt[ now] [ val] == - 1 ) nxt[ now] [ val] = newnode ( ) ;
now= nxt[ now] [ val] ;
}
ed[ now] ++ ;
}
void build ( ) {
queue< int > q;
fail[ rt] = rt;
for ( int i= 0 ; i< R; i++ ) {
if ( nxt[ rt] [ i] == - 1 ) nxt[ rt] [ i] = rt;
else {
fail[ nxt[ rt] [ i] ] = rt;
q. push ( nxt[ rt] [ i] ) ;
}
}
while ( ! q. empty ( ) ) {
int now= q. front ( ) ; q. pop ( ) ;
for ( int i= 0 ; i< R; i++ ) {
if ( nxt[ now] [ i] == - 1 ) nxt[ now] [ i] = nxt[ fail[ now] ] [ i] ;
else {
fail[ nxt[ now] [ i] ] = nxt[ fail[ now] ] [ i] ;
q. push ( nxt[ now] [ i] ) ;
}
}
}
}
int query ( char * s) {
int now= rt, res= 0 , len= strlen ( s) ;
for ( int i= 0 ; i< len; i++ ) {
int val= s[ i] - 'a' ;
now= nxt[ now] [ val] ;
int tmp= now;
while ( tmp!= rt) {
res+ = ed[ tmp] ;
ed[ tmp] = 0 ;
tmp= fail[ tmp] ;
}
}
return res;
}
} ac;
马拉车:
void manacher ( char * s) {
int len= strlen ( s) ;
for ( int i= len; i>= 0 ; -- i) {
s[ i+ i+ 2 ] = s[ i] ;
s[ i+ i+ 1 ] = '#' ;
}
s[ 0 ] = '*' ;
int k= 1 , maxlen= 0 ;
for ( int i= 2 ; i< len+ len+ 1 ; ++ i) {
int maxr= k+ p[ k] - 1 ;
p[ i] = min ( p[ 2 * k- i] , max ( maxr- i+ 1 , 1 ) ) ;
while ( s[ i- p[ i] ] == s[ i+ p[ i] ] ) ++ p[ i] ;
if ( i+ p[ i] > k+ p[ k] ) k= i;
if ( p[ i] > maxlen) maxlen= p[ i] ;
}
}
回文树:
const int MAXN = 100005 ;
const int N = 26 ;
struct Palindromic_Tree {
int next[ MAXN] [ N] ;
int fail[ MAXN] ;
int cnt[ MAXN] ;
int num[ MAXN] ;
int len[ MAXN] ;
int S[ MAXN] ;
int last ;
int n ;
int p ;
int pos[ MXAN] ;
int newnode ( int l ) {
for ( int i = 0 ; i < N ; ++ i ) next[ p] [ i] = 0 ;
cnt[ p] = 0 ;
num[ p] = 0 ;
len[ p] = l ;
return p ++ ;
}
void init ( ) {
p = 0 ;
newnode ( 0 ) ;
newnode ( - 1 ) ;
last = 0 ;
n = 0 ;
S[ n] = - 1 ;
fail[ 0 ] = 1 ;
}
int get_fail ( int x ) {
while ( S[ n - len[ x] - 1 ] != S[ n] ) x = fail[ x] ;
return x ;
}
void add ( int c ) {
c - = 'a' ;
S[ ++ n] = c ;
int cur = get_fail ( last ) ;
if ( ! next[ cur] [ c] ) {
int now = newnode ( len[ cur] + 2 ) ;
fail[ now] = next[ get_fail ( fail[ cur] ) ] [ c] ;
next[ cur] [ c] = now ;
num[ now] = num[ fail[ now] ] + 1 ;
}
last = next[ cur] [ c] ;
cnt[ last] ++ ;
pos[ last] = n;
}
void count ( ) {
for ( int i = p - 1 ; i >= 0 ; -- i ) cnt[ fail[ i] ] + = cnt[ i] ;
}
} ;
后缀数组:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = ( int ) 1e6 + 10 ;
int wa[ MAXN] , wb[ MAXN] , wv[ MAXN] , we[ MAXN] , rk[ MAXN] ;
int cmp ( int * r, int a, int b, int l) { return r[ a] == r[ b] && r[ a+ l] == r[ b+ l] ; }
void build_sa ( int * r, int * sa, int n, int m) {
int i, j, p, * x= wa, * y= wb, * t;
for ( i= 0 ; i< m; i++ ) we[ i] = 0 ;
for ( i= 0 ; i< n; i++ ) we[ x[ i] = r[ i] ] ++ ;
for ( i= 1 ; i< m; i++ ) we[ i] + = we[ i- 1 ] ;
for ( i= n- 1 ; i>= 0 ; i-- ) sa[ -- we[ x[ i] ] ] = i;
for ( j= 1 , p= 1 ; p< n; j* = 2 , m= p) {
for ( p= 0 , i= n- j; i< n; i++ ) y[ p++ ] = i;
for ( i= 0 ; i< n; i++ ) if ( sa[ i] >= j) y[ p++ ] = sa[ i] - j;
for ( i= 0 ; i< n; i++ ) wv[ i] = x[ y[ i] ] ;
for ( i= 0 ; i< m; i++ ) we[ i] = 0 ;
for ( i= 0 ; i< n; i++ ) we[ wv[ i] ] ++ ;
for ( i= 1 ; i< m; i++ ) we[ i] + = we[ i- 1 ] ;
for ( i= n- 1 ; i>= 0 ; i-- ) sa[ -- we[ wv[ i] ] ] = y[ i] ;
for ( t= x, x= y, y= t, p= 1 , x[ sa[ 0 ] ] = 0 , i= 1 ; i< n; i++ )
x[ sa[ i] ] = cmp ( y, sa[ i- 1 ] , sa[ i] , j) ? p- 1 : p++ ;
}
}
int height[ MAXN] ;
void calheight ( int * r, int * sa, int n) {
int i, j, k= 0 ;
for ( i= 1 ; i<= n; i++ ) rk[ sa[ i] ] = i;
for ( i= 0 ; i< n; height[ rk[ i++ ] ] = k) {
for ( k? k-- : 0 , j= sa[ rk[ i] - 1 ] ; r[ i+ k] == r[ j+ k] ; k++ ) ;
}
}
int sa[ MAXN] , a[ MAXN] ;
char str[ MAXN] ;
int main ( )
{
scanf ( "%s" , str) ;
int n= strlen ( str) ;
for ( int i= 0 ; i< n; i++ ) a[ i] = str[ i] ;
a[ n] = 0 ;
build_sa ( a, sa, n+ 1 , 128 ) ;
calheight ( a, sa, n) ;
for ( int i= 1 ; i<= n; i++ ) printf ( "%d " , sa[ i] + 1 ) ;
printf ( "\n" ) ;
for ( int i= 2 ; i<= n; i++ ) printf ( "%d " , height[ i] ) ;
printf ( "\n" ) ;
return 0 ;
}
后缀自动机:
const int M= 1000100 ;
char s[ M] ;
int epos[ M] , len[ M] , nxt[ M] [ 26 ] , link[ M] , f[ M] ;
int w[ M] , q[ M] ;
int n, T, K;
struct sam{
int root, last, cnt;
sam ( ) { root= last= ++ cnt; }
void insert ( int c) {
int np= ++ cnt, p= last; last= np;
epos[ np] = 1 ; len[ np] = len[ p] + 1 ;
for ( ; p&& ! nxt[ p] [ c] ; nxt[ p] [ c] = np, p= link[ p] ) ;
if ( ! p) link[ np] = root;
else if ( len[ nxt[ p] [ c] ] == len[ p] + 1 ) link[ np] = nxt[ p] [ c] ;
else {
int nq= ++ cnt, q= nxt[ p] [ c] ; len[ nq] = len[ p] + 1 ;
memcpy ( nxt[ nq] , nxt[ q] , sizeof nxt[ q] ) ; link[ nq] = link[ q] ;
link[ np] = link[ q] = nq;
for ( ; p&& nxt[ p] [ c] == q; nxt[ p] [ c] = nq, p= link[ p] ) ;
}
}
void build ( ) {
scanf ( "%s" , s+ 1 ) ; n= strlen ( s+ 1 ) ;
for ( int i= 1 ; i<= n; i++ ) insert ( s[ i] - 'a' ) ;
}
void topsort ( ) {
for ( int i= 1 ; i<= cnt; i++ ) w[ len[ i] ] ++ ;
for ( int i= 1 ; i<= n; i++ ) w[ i] + = w[ i- 1 ] ;
for ( int i= 1 ; i<= cnt; i++ ) q[ w[ len[ i] ] -- ] = i;
}
} SAM;