Ural 1960 Palindromes and Super Abilities

Palindromes and Super Abilities

Time Limit: 1000ms
Memory Limit: 65536KB
This problem will be judged on Ural. Original ID: 1960
64-bit integer IO format: %lld      Java class name: (Any)
After solving seven problems on Timus Online Judge with a word “palindrome” in the problem name, Misha has got an unusual ability. Now, when he reads a word, he can mentally count the number of unique nonempty substrings of this word that are palindromes.
Dima wants to test Misha’s new ability. He adds letters s1, ..., sn to a word, letter by letter, and after every letter asks Misha, how many different nonempty palindromes current word contains as substrings. Which n numbers will Misha say, if he will never be wrong?
 

Input

The only line of input contains the string s1...sn, where si are small English letters (1 ≤ n ≤ 105).
 

Output

Output n numbers separated by whitespaces, i-th of these numbers must be the number of different nonempty substrings of prefix s1...si that are palindromes.
 

Sample Input

aba

Sample Output

1 2 3

Source

 
解题:PalindromicTree
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 100010;
 4 struct PalindromicTree{
 5     int fail[maxn],len[maxn],son[maxn][26];
 6     int tot,last,n;
 7     char s[maxn];
 8     int newnode(int slen = 0){
 9         memset(son[tot],0,sizeof son[tot]);
10         len[tot] = slen;
11         return tot++;
12     }
13     void init(){
14         n = tot = last = 0;
15         newnode(0);
16         newnode(-1);
17         fail[1] = fail[0] = 1;
18         s[n] = -1;
19     }
20     int getFail(int x){
21         while(s[n - len[x] - 1] != s[n]) x = fail[x];
22         return x;
23     }
24     void extend(int c){
25         s[++n] = c;
26         int cur = getFail(last);
27         if(!son[cur][c]){
28             int x = newnode(len[cur] + 2);
29             fail[x] = son[getFail(fail[cur])][c];
30             son[cur][c] = x;
31         }
32         last = son[cur][c];
33     }
34 }pt;
35 char str[maxn];
36 int main(){
37     while(~scanf("%s",str)){
38         pt.init();
39         bool flag = false;
40         for(int i = 0; str[i]; ++i){
41             pt.extend(str[i] - 'a');
42             if(flag) putchar(' ');
43             printf("%d",pt.tot - 2);
44             flag = true;
45         }
46         putchar('\n');
47     }
48     return 0;
49 }
View Code

 

posted @ 2015-10-27 13:20  狂徒归来  阅读(281)  评论(0编辑  收藏  举报