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, ...,  s n 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... s n, where  s i 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... s i 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

 

转载于:https://www.cnblogs.com/crackpotisback/p/4913902.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值