HDU 4622 Reincarnation 后缀自动机
2013-08-03 18:58
337 查看
模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747
解法参考:/article/2500902.html
刚学后缀自动机,还是有很多性质不是很了解……目前也就能做个模板题orz
推荐几篇学习后缀自动机的文章:
陈立杰课件:http://wenku.baidu.com/view/7afa5828ed630b1c59eeb512.html
推荐资料:
http://www.neroysq.com/?p=76
http://fanhq666.blog.163.com/blog/static/8194342620123352232937/
http://hi.baidu.com/myidea/item/142c5cd45901a51820e25039
http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html
解法参考:/article/2500902.html
刚学后缀自动机,还是有很多性质不是很了解……目前也就能做个模板题orz
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; #define N 2010 #define MAXQ 10010 struct Suffix_Automaton { int F[N << 1],ant,last,ch[N << 1][26],step[N << 1]; void init() { last = ant = 1; memset(F,0,sizeof(F)); memset(ch,0,sizeof(ch)); memset(step,0,sizeof(step)); } void ins(int x) { int t = ++ant, pa = last; step[t] = step[last] + 1; last = t; for( ; pa && !ch[pa][x]; pa = F[pa] ) ch[pa][x] = t; if( pa == 0 ) F[t] = 1; else if( step[pa] + 1 == step[ ch[pa][x] ] ) F[t] = ch[pa][x]; else { int nq = ++ant, q = ch[pa][x]; memcpy( ch[nq], ch[q], sizeof(ch[nq]) ); step[nq] = step[pa] + 1; F[nq] = F[q]; F[q] = F[t] = nq; for( ; pa && ch[pa][x] == q; pa = F[pa] ) ch[pa][x] = nq; } } }; //以上为后缀自动机模板 struct node { int l, r; int id; }; node qry[MAXQ]; char str[2010]; int ans[MAXQ]; Suffix_Automaton SAM; bool cmp( node a, node b ) { if ( a.l == b.l ) return a.r < b.r; return a.l < b.l; } int main() { int T; scanf( "%d", &T ); while ( T-- ) { scanf( "%s", &str[1] ); int Q; scanf( "%d", &Q ); for ( int i = 0; i < Q; ++i ) { scanf("%d%d", &qry[i].l, &qry[i].r ); qry[i].id = i; } sort( qry, qry + Q, cmp ); int preL = qry[0].l; SAM.init(); int j = preL; for ( int i = 0; i < Q; ++i ) { if ( qry[i].l == preL ) { while ( j <= qry[i].r ) { SAM.ins( str[j] - 'a' ); ++j; } int tmp = 0; for ( int k = SAM.ant; k > 0; --k ) tmp += SAM.step[k] - SAM.step[ SAM.F[k] ]; ans[ qry[i].id ] = tmp; } else { preL = qry[i].l; j = qry[i].l; SAM.init(); while ( j <= qry[i].r ) { SAM.ins( str[j] - 'a' ); ++j; } int tmp = 0; for ( int k = SAM.ant; k > 0; --k ) tmp += SAM.step[k] - SAM.step[ SAM.F[k] ]; ans[ qry[i].id ] = tmp; } } for ( int i = 0; i < Q; ++i ) printf( "%d\n", ans[i] ); } return 0; }
推荐几篇学习后缀自动机的文章:
陈立杰课件:http://wenku.baidu.com/view/7afa5828ed630b1c59eeb512.html
推荐资料:
http://www.neroysq.com/?p=76
http://fanhq666.blog.163.com/blog/static/8194342620123352232937/
http://hi.baidu.com/myidea/item/142c5cd45901a51820e25039
http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html
相关文章推荐
- HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
- [后缀自动机 模板题 || 字符串Hash] HDU 4622 Reincarnation
- hdu 4622 Reincarnation(后缀自动机,入门级)
- hdu 4622 Reincarnation(后缀自动机)
- hdu 4622 Reincarnation (后缀自动机)
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
- hdu 4622 Reincarnation (后缀自动机)
- HDU 4622 Reincarnation 后缀自动机
- 字符串(后缀自动机):HDU 4622 Reincarnation
- hdu 4622 Reincarnation (后缀自动机)
- HDU 4622 Reincarnation 后缀数组 或 后缀自动机
- HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)
- HDU 4622 Reincarnation(后缀自动机)
- HDU 4622 Reincarnation(后缀自动机)
- HDU 4622 Reincarnation (区间不相同子串个数:字符串哈希 | 后缀数组 | 后缀自动机)
- HDU - 4622 Reincarnation 后缀自动机
- Hdu 4622 Reincarnation 后缀数组/后缀自动机
- HDU 4622 (后缀自动机)
- HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描