看上去像是回文串自动机的模板题,就来了一发
The Number of Palindromes
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1992 Accepted Submission(s): 694
Problem Description
Now, you are given a string S. We want to know how many distinct substring of S which is palindrome.
Input
The first line of the input contains a single integer T(T<=20), which indicates number of test cases.
Each test case consists of a string S, whose length is less than 100000 and only contains lowercase letters.
Output
For every test case, you should output "Case #k:" first in a single line, where k indicates the case number and starts at 1. Then output the number of distinct substring of S which is palindrome.
Sample Input
3 aaaa abab abcd
Sample Output
Case #1: 4 Case #2: 4 Case #3: 4
Source
2011 Multi-University Training
Contest 11 - Host by UESTC
/* *********************************************** Author :CKboss Created Time :2015年04月17日 星期五 09时38分22秒 File Name :pt.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int C=30; const int maxn=120000; struct Node { Node *ch[C],*suffix; int len; }bar[maxn],*foo,*last,*odd,*even; char s[maxn]; int n,cnt; // cnt=foo-bar=count of palindromes , n the number of char added void init() { odd=bar; even=last=odd+1; foo=even+1; memset(odd->ch,0,sizeof(odd->ch)); memset(even->ch,0,sizeof(even->ch)); odd->suffix=even->suffix=odd; odd->len=-1; even->len=0; n=0; cnt=0; } Node* New_Node(int x) { memset(foo->ch,0,sizeof(foo->ch)); foo->len=x; return foo++; } int index(char x) { return x-'a'; } Node* get(Node*p) { while(n-p->len-2<0||s[n-p->len-2]!=s[n-1]) p=p->suffix; return p; } bool add(char c) { int x=index(c); s[n++]=c; Node* p =get(last); if(!p->ch[x]) { last = New_Node(p->len+2); if(last->len==1) last->suffix=even; else last->suffix=get(p->suffix)->ch[x]; /// guarantee proper suffix p->ch[x]=last; cnt++; return true; } else { last=p->ch[x]; return false; } } char str[maxn]; int main() { int T_T,cas=1; scanf("%d",&T_T); while(T_T--) { scanf("%s",str); int len=strlen(str); init(); for(int i=0;i<len;i++) { add(str[i]); } printf("Case #%d: %d\n",cas++,cnt); } }