HDU 4622 Reincarnation 后缀自动机

模板来源: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\n", ans[i] );

116     }

117     return 0;

118 }

推荐几篇学习后缀自动机的文章:

陈立杰课件: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)