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 }