URAL 2040 (回文自动机)

Problem Palindromes and Super Abilities 2 (URAL2040)

题目大意

  给一个字符串,从左到右依次添加,询问每添加一个字符,新增加的回文串数量。

解题分析

  用回文自动机来做,如果新添加了一个字符,自动机中新开了一个节点,说明新增加了一个回文串。

  对于每新添加一个字符,新增加的回文串数量最多为1。

  另外,这道题既卡空间又卡时间,交了n发才过。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 #pragma comment(linker,"/STACK:102400000,102400000")
15 using namespace std;
16 
17 #define     N             5000008
18 #define     V             1008
19 #define        E            60008    
20 #define        lson        l,m,rt<<1
21 #define     rson        m,r+1,rt<<1|1
22 #define        clr(x,v)    memset(x,v,sizeof(x));
23 #define        LL            long long 
24 
25 const int    mo    =    1000000007;
26 const int     inf =    0x3f3f3f3f;
27 const int     INF =    2000000000;
28 /**************************************************************************/ 
29 int n,cnt,last;
30 int nt[N][2],size[N],len[N],fail[N];
31 char s[N];
32 
33 void init(){
34     fail[0]=fail[1]=1;
35     len[1]=-1;
36     last=0; cnt=1;
37 }
38 void insert(int c,int n){
39     int p=last;
40     while (s[n-len[p]-1]!=s[n]) p=fail[p];
41     if (!nt[p][c]){
42         int now=++cnt,k=fail[p];
43         len[now]=len[p]+2; 
44         while (s[n-len[k]-1]!=s[n]) k=fail[k];
45         fail[now]=nt[k][c]; nt[p][c]=now;
46         putchar('1');
47     }
48     else putchar("0");
49     last=nt[p][c];
50     size[last]++;
51 }
52 
53 void solve(){
54     for (int i=cnt;i>=1;i--) size[fail[i]]+=size[i];
55 }
56 int main(){
57     gets(s+1);
58     init();
59     n=strlen(s+1);
60     for (int i=1;i<=n;i++) insert(s[i]-97,i);
61 }
View Code
原文地址:https://www.cnblogs.com/rpSebastian/p/5747468.html