HDU5394-Trie in Tina Town

来源:互联网 发布:c语言实现串口通信 编辑:程序博客网 时间:2024/06/07 21:08

Trie in Tina Town

                                                                 Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
                                                                                             Total Submission(s): 773    Accepted Submission(s): 132


Problem Description
Tina Town is a friendly place. People there care about each other.

A trie which was planted by the first mayor of Tina Town grows in the center of the town.

We define a palindrome substring in a trie a string that is a suffix of a string which the path from the root to any node represents and the string is a palindrome. Two palindromes are different if and only if their positions are different. Now, Tina wants to know the sum of the length of all palindrome substrings. Tina didn’t know the answer so she asked you to find out the answer for her.
 

Input
The first line contains a integer – number of cases
For each case, the first line is an integer N representing the number of nodes in trie except the root.
The following N lines contains a letter between a and d – the letter that node n[i] stores and a number f[i] – the index of n[i]’s father. It’s guaranteed that fa[i]i. If fa[i]=0 n[i] is the root.
T10,N2106
 

Output
The first line contains a integer – number of cases
For each case, the first line is an integer N representing the number of nodes in trie except the root.
The following N lines contains a letter between a and d – the letter that node n[i] stores and a number f[i] – the index of n[i]’s father. It’s guaranteed that fa[i]i. If fa[i]=0 n[i] is the root.
T10,N2106
 

Sample Input
25a 0a 1a 2b 1b 45a 0a 1a 2b 1a 4
 

Sample Output
1415
Hint
The first test case is a trie like this:aaa *1 -> 3aa *2 -> 4a *3-> 3b *2-> 2bb *1- > 23+4+3+2+2 = 14The second test case:aaa *1 -> 3aba *1 -> 3a *4 -> 4b *1 -> 1aa *2 -> 43+3+4+1+4 = 15If the stack size is too small, you can submit it in C++ and add ‘#pragma comment(linker, "/STACK:102400000,102400000”)’ at the head of your program.Large input, recommend to use fast I/O.
 

Source
BestCoder Round #51 (div.2)
 

Recommend
hujie
 


题目:给出一个以0为根节点的树,每个节点有一个字符,求树上的价值=sum(len*cnt),len为回文串长度,cnt为该回文在树上出现的次数。一共只有a,b,c,d这几种字符,回文串要保证是从上到下的。

解题思路:回文树,把last改为数组保存每个节点的last即可


#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <map>#include <set>#include <stack>#include <queue>#include <vector>#include <bitset>#include <functional>using namespace std;#define LL long longconst int INF = 0x3f3f3f3f;const int maxn = 2e6 + 10;char s[maxn];int n, x;int ss[maxn], nt[maxn];LL ans;struct PalindromicTree{const static int maxn = 2e6 + 10;int next[maxn][4], last[maxn], sz, tot;int fail[maxn], len[maxn];LL cnt[maxn];char s[maxn];void Clear(){len[1] = -1; len[2] = 0;fail[2] = fail[1] = 1;last[0] = (sz = 3) - 1;cnt[1] = cnt[2] = tot = 0;memset(next[1], 0, sizeof(next[1]));memset(next[2], 0, sizeof(next[2]));}int Node(int length){memset(next[sz], 0, sizeof(next[sz]));len[sz] = length;return sz;}int getfail(int x){while (s[tot] != s[tot - len[x] - 1]) x = fail[x];return x;}LL add(char pos){int x = (s[++tot] = pos) - 'a', y = getfail(last[tot - 1]);if (next[y][x]) return cnt[last[tot] = next[y][x]];last[tot] = next[y][x] = Node(len[y] + 2);fail[sz] = len[sz] == 1 ? 2 : next[getfail(fail[y])][x];cnt[sz] = cnt[fail[sz]] + len[sz]; sz++;return cnt[last[tot]];}}solve;void dfs(int k){for (int i = ss[k]; ~i; i = nt[i]){ans += solve.add(s[i]);dfs(i);solve.tot--;}}int main(){int t;scanf("%d", &t);while (t--){ans = 0;solve.Clear();memset(ss, -1, sizeof ss);scanf("%d", &n);for (int i = 1; i <= n; i++){scanf("%s%d", s + i, &x);nt[i] = ss[x], ss[x] = i;}dfs(0);printf("%lld\n", ans);}return 0;}