HDU5658:CA Loves Palindromic (回文树,求区间本质不同的回文串数)
CA loves strings, especially loves the palindrome strings.
One day he gets a string, he wants to know how many palindromic substrings in the substring S
.
Attantion, each same palindromic substring can only be counted once.
InputFirst line contains T denoting the number of testcases.
Attantion, each same palindromic substring can only be counted once.
T testcases follow. For each testcase:
First line contains a string S. We ensure that it is contains only with lower case letters.
Second line contains a interger Q, denoting the number of queries.
Then Q lines follow, In each line there are two intergers l,r, denoting the substring which is queried.
1≤T
OutputFor each testcase, output the answer in Q lines.Sample Input
1 abba 2 1 2 1 3Sample Output
2 3
题意:给定字符串S,|S|<1000;Q次询问区间不用本质的回文串数量。
思路:以每个左端点建立回文树即可。 注意判定边界,即给第0位赋值-1啥的,我之前的板子没有,害我wa了几发。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=1010; char c[maxn]; int bb[maxn]; int N,Q,fcy[maxn][maxn]; struct PT { struct node{ int fail,len,son[26]; }t[maxn]; int tot,last; void init() { memset(t,0,sizeof(t)); t[0].fail=t[1].fail=1; t[1].len=-1; last=1; tot=1; bb[0]=-1; bb[1]=-2; } void add(int s,int n) { int p=last; bb[n]=s; while(bb[n-t[p].len-1]!=bb[n]) p=t[p].fail; if(!t[p].son[s]) { int v=++tot,k=t[p].fail; t[v].len=t[p].len+2; while(bb[n-t[k].len-1]!=bb[n]) k=t[k].fail; t[v].fail=t[k].son[s]; t[p].son[s]=v; } last=t[p].son[s]; } }T; void solve() { rep(i,1,N){ T.init(); rep(j,i,N) { T.add(c[j]-'a',j-i+1); fcy[i][j]=T.tot-1; } } scanf("%d",&Q); rep(i,1,Q){ int L,R; scanf("%d%d",&L,&R); printf("%d\n",fcy[L][R]); } } int main() { int T;scanf("%d",&T); while(T--){ memset(c,0,sizeof(c)); scanf("%s",c+1); N=strlen(c+1); solve(); } return 0; }
It is your time to fight!