模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747
解法参考:http://blog.csdn.net/dyx404514/article/details/9631787
刚学后缀自动机,还是有很多性质不是很了解……目前也就能做个模板题orz
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 6 using namespace std; 7 8 #define N 2010 9 #define MAXQ 10010 10 11 struct Suffix_Automaton 12 { 13 int F[N << 1],ant,last,ch[N << 1][26],step[N << 1]; 14 15 void init() 16 { 17 last = ant = 1; 18 memset(F,0,sizeof(F)); 19 memset(ch,0,sizeof(ch)); 20 memset(step,0,sizeof(step)); 21 } 22 23 void ins(int x) 24 { 25 int t = ++ant, pa = last; 26 step[t] = step[last] + 1; 27 last = t; 28 for( ; pa && !ch[pa][x]; pa = F[pa] ) 29 ch[pa][x] = t; 30 if( pa == 0 ) F[t] = 1; 31 else if( step[pa] + 1 == step[ ch[pa][x] ] ) 32 F[t] = ch[pa][x]; 33 else 34 { 35 int nq = ++ant, q = ch[pa][x]; 36 memcpy( ch[nq], ch[q], sizeof(ch[nq]) ); 37 step[nq] = step[pa] + 1; 38 F[nq] = F[q]; 39 F[q] = F[t] = nq; 40 for( ; pa && ch[pa][x] == q; pa = F[pa] ) 41 ch[pa][x] = nq; 42 } 43 } 44 }; 45 //以上为后缀自动机模板 46 47 struct node 48 { 49 int l, r; 50 int id; 51 }; 52 53 node qry[MAXQ]; 54 char str[2010]; 55 int ans[MAXQ]; 56 Suffix_Automaton SAM; 57 58 bool cmp( node a, node b ) 59 { 60 if ( a.l == b.l ) return a.r < b.r; 61 return a.l < b.l; 62 } 63 64 int main() 65 { 66 int T; 67 scanf( "%d", &T ); 68 while ( T-- ) 69 { 70 scanf( "%s", &str[1] ); 71 int Q; 72 scanf( "%d", &Q ); 73 for ( int i = 0; i < Q; ++i ) 74 { 75 scanf("%d%d", &qry[i].l, &qry[i].r ); 76 qry[i].id = i; 77 } 78 sort( qry, qry + Q, cmp ); 79 80 int preL = qry[0].l; 81 SAM.init(); 82 int j = preL; 83 for ( int i = 0; i < Q; ++i ) 84 { 85 if ( qry[i].l == preL ) 86 { 87 while ( j <= qry[i].r ) 88 { 89 SAM.ins( str[j] - 'a' ); 90 ++j; 91 } 92 int tmp = 0; 93 for ( int k = SAM.ant; k > 0; --k ) 94 tmp += SAM.step[k] - SAM.step[ SAM.F[k] ]; 95 ans[ qry[i].id ] = tmp; 96 } 97 else 98 { 99 preL = qry[i].l; 100 j = qry[i].l; 101 SAM.init(); 102 while ( j <= qry[i].r ) 103 { 104 SAM.ins( str[j] - 'a' ); 105 ++j; 106 } 107 int tmp = 0; 108 for ( int k = SAM.ant; k > 0; --k ) 109 tmp += SAM.step[k] - SAM.step[ SAM.F[k] ]; 110 ans[ qry[i].id ] = tmp; 111 } 112 } 113 114 for ( int i = 0; i < Q; ++i ) 115 printf( "%d ", ans[i] ); 116 } 117 return 0; 118 }
推荐几篇学习后缀自动机的文章:
陈立杰课件:http://wenku.baidu.com/view/7afa5828ed630b1c59eeb512.html
推荐资料:
http://fanhq666.blog.163.com/blog/static/8194342620123352232937/