The Problem to Slow Down You
64-bit integer IO format: %I64d Java class name: (Any)
“Oh, why do you guys think about that?” Federmann smiled. “Don’t they know I have an Edward number2 of 3?”
He then thought about something about palindrome, given two strings A and B, what is the number of their common palindrome substrings? The amount of common palindrome
substrings between two strings is defined as the number of quadruple (p, q, s, t), which satisfies that:
1. 1 ≤ p, q ≤ length(A), 1 ≤ s, t ≤ length(B), p ≤ q and s ≤ t. Here length(A) means the length of string A.
2. Ap..q = Bs..t
3. Ap..q is palindrome. (palindrome string is the string that reads the same forward or
backward) For example, (1, 3, 1, 3) and (1, 3, 3, 5) are both considered as a valid common palindrome
substring between aba and ababa. Federmann is excited about his new task, and he is just too lazy to write solutions, help
him.
Input
The first line of the input gives the number of test cases, T. T test cases follow. For each
test case, the first line contains a string A and the second line contains a string B. The length
of A, B will not exceed 200000.
It is guaranteed the input file will be smaller than 8 MB.
Output
For each test case, output one line containing “Case #x: y”, where x is the test case
number (starting from 1) and y is the number of common palindrome substrings of A and B.
Samples
Sample Input
3
abacab
abccab
faultydogeuniversity
hasnopalindromeatall
abbacabbaccab
youmayexpectedstrongsamplesbutnow
Sample Output
Case #1: 12
Case #2: 20
Case #3: 18
Source
解题:回文机
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 200010; 5 const int N = 26; 6 struct PalindromicTree { 7 int next[maxn][N],cnt[maxn],fail[maxn]; 8 int len[maxn],s[maxn],num[maxn]; 9 int tot,last,n; 10 int newnode(int length) { 11 memset(next[tot],0,sizeof next[tot]); 12 len[tot] = length; 13 cnt[tot] = num[tot] = 0; 14 return tot++; 15 } 16 int get_fail(int x) { 17 while(s[n - len[x] - 1] != s[n]) x = fail[x]; 18 return x; 19 } 20 void init() { 21 last = tot = n = 0; 22 newnode(0); 23 newnode(-1); 24 fail[0] = 1; 25 s[n] = -1; 26 } 27 void count() { 28 for(int i = tot-1; i >= 0; --i) 29 cnt[fail[i]] += cnt[i]; 30 } 31 void add(int c) { 32 c -= 'a'; 33 s[++n] = c; 34 int cur = get_fail(last); 35 if(!next[cur][c]) { 36 int now = newnode(len[cur] + 2); 37 fail[now] = next[get_fail(fail[cur])][c]; 38 next[cur][c] = now; 39 num[now] = num[fail[now]] + 1; 40 } 41 last = next[cur][c]; 42 cnt[last]++; 43 } 44 } a,b; 45 LL ret; 46 void dfs(int u,int v) { 47 for(int i = 0; i < N; ++i) { 48 int x = a.next[u][i]; 49 int y = b.next[v][i]; 50 if(x && y) { 51 ret += (LL)a.cnt[x]*b.cnt[y]; 52 dfs(x,y); 53 } 54 } 55 } 56 char str[maxn]; 57 int main() { 58 int kase,cs = 1; 59 scanf("%d",&kase); 60 while(kase--) { 61 a.init(); 62 b.init(); 63 scanf("%s",str); 64 for(int i = 0; str[i]; ++i) a.add(str[i]); 65 scanf("%s",str); 66 for(int i = 0; str[i]; ++i) b.add(str[i]); 67 a.count(); 68 b.count(); 69 ret = 0; 70 dfs(0,0); 71 dfs(1,1); 72 printf("Case #%d: %I64d\n",cs++,ret); 73 } 74 return 0; 75 }