Finding Palindromes
Time Limit: 10000MS   Memory Limit: 262144K
Total Submissions: 4043   Accepted: 746
Case Time Limit: 2000MS

Description

A word is called a palindrome if we read from right to left is as same as we read from left to right. For example, "dad", "eye" and "racecar" are all palindromes, but "odd", "see" and "orange" are not palindromes.

Given n strings, you can generate n × n pairs of them and concatenate the pairs into single words. The task is to count how many of the so generated words are palindromes.

Input

The first line of input file contains the number of strings n. The following n lines describe each string:

The i+1-th line contains the length of the i-th string li, then a single space and a string of li small letters of English alphabet.

You can assume that the total length of all strings will not exceed 2,000,000. Two strings in different line may be the same.

Output

Print out only one integer, the number of palindromes.

Sample Input

3
1 a
2 ab
2 ba

Sample Output

5

Hint

The 5 palindromes are:
aa aba aba abba baab
 
 
http://blog.csdn.net/acblacktea/article/details/51884850  //转载这篇博客
 
#include<cstdio>
#include<cstring>
#include<vector>
typedef long long LL;
using namespace std;
const int N=;
struct node{
int sum,son[],cnt;
}no[N];
struct str{
int start,en;
str(int s,int e):start(s),en(e){};
str(){};
};
vector<str>ve;
int fla[N][],nexta[N],tot=,n,pre,l;
char s[N],t[N];
void getNext(char *a,int la){
int i=,j=-;
nexta[]=-;
while(i<la){
if(j==-||a[i]==a[j]) nexta[++i]=++j;
else j=nexta[j];
}
}
void kmp(int flag,char *a,char *b,int la,int start){
int i=,j=;
while(i<la){
if(j==-||a[j]==b[i]) ++i,++j;
else j=nexta[j];
}
int pre=j;
if(!flag) {
while(pre){
fla[start+pre-][]=;
pre=nexta[pre];
}
}
else {
while(pre){
fla[start+l-pre][]=;
pre=nexta[pre];
}
}
}
void insertTire(int pre,char *a,int start,int la)//储存前缀
{
for(int i=;i<l;i++)
{
if(!no[pre].son[a[i]-'a'])
{
tot++;
no[pre].son[a[i]-'a'] = tot;
pre = tot;
}
else pre = no[pre].son[a[i]-'a'];
if(i+<la)no[pre].cnt+=fla[start+i+][];
}
no[pre].sum++;
}
LL findTrie(int start,int en,int pre){
int sym=true;
LL ans=;
int l=en-start;
for(int i=start;i<en;++i) {
if(no[pre].son[t[i]-'a']) {
pre=no[pre].son[t[i]-'a'];
if(fla[start+l-(i-start+)-][]||i==en-) ans+=no[pre].sum;
}
else {
sym=;break;
}
}
if(sym) ans+=no[pre].cnt;
return ans;
}
int main(){
pre=;
LL ans=;
for(scanf("%d",&n);n--;){
scanf("%d %s",&l,s+pre);
ve.push_back(str(pre,pre+l));
for(int i=pre;i<pre+l;++i) t[i]=s[pre+l-(i-pre+)];
getNext(s+pre,l);
kmp(,s+pre,t+pre,l,pre);
getNext(t+pre,l);
kmp(,t+pre,s+pre,l,pre);
insertTire(,s+pre,pre,l);
pre+=l;
}
for(int i=;i<(int)ve.size();++i) ans+=findTrie(ve[i].start,ve[i].en,);
printf("%I64d\n",ans);
}

poj3376 KMP+字典树求回文串数量(n*n)的更多相关文章

  1. Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome 字典树/半回文串

    E. Ann and Half-Palindrome Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contes ...

  2. 拓展KMP求回文串

    题目:hdu3613: 题意:有26字母对应的价值,然后给出以个串,把它分成两段字串,如果字串是回文串,串的价值就是每个字符和,不是就为0.求最大价值. 博客 分析:拓展KMP的应用求回文字串. #i ...

  3. 2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对)

    2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对) https://www.luogu.com.cn/problem/P5041 题意: 给一个字符串 \(S\) ,每 ...

  4. Palindrome - URAL - 1297(求回文串)

    题目大意:RT   分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的.   线段数+后缀数组代码如下: ...

  5. manacher算法,求回文串

    用来求字符串最长回文串或者回文串的总数量 #include<map> #include<queue> #include<stack> #include<cma ...

  6. 马拉车,O(n)求回文串

    马拉车,O(n)求回文串 对整个马拉车算法步骤做个总结: 第一步:将每个原字母用两个特殊字符包围如: aaa --> #a#a#a# abab -->#a#b#a#b 同时可以由这个翻倍的 ...

  7. HDU 3613 Best Reward ( 拓展KMP求回文串 || Manacher )

    题意 : 给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串,那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0.问 ...

  8. 3676: [Apio2014]回文串 求回文串长度与出现次数的最大值

    「BZOJ3676」[Apio2014] 回文串   Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所 ...

  9. hdu 3294 manacher 求回文串

    感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...

随机推荐

  1. Spring Boot JPA的查询语句

    文章目录 准备工作 Containing, Contains, IsContaining 和 Like StartsWith EndsWith 大小写不敏感 Not @Query Spring Boo ...

  2. 【Linux常见命令】mv命令

    mv - move (rename) files mv命令用来为文件或目录改名.或将文件或目录移入其它位置. 语法: mv [OPTION]... [-T] SOURCE DEST mv [OPTIO ...

  3. Vue Cli 3 打包上线 部署到Apache Tomcat服务器

    使用 npm run build 打包项目 在根目录中有一个dist文件夹 我使用的服务器是 Apache  Tomcat 把项目放进tomcat /webapps 中 启动服务器 <mac O ...

  4. Get on the CORBA

    from: <The Common Object Request Broker: Architecture and Specification> Client To make a requ ...

  5. SQL 文件导入数据库

    1.首先通过 xshell 连接数据库服务器,执行命令 mysql -u root -p 命令,按照提示输入密码,连接上数据库 2.在连接终端上执行命令 create database JD_Mode ...

  6. OSG程序设计之Hello World1.0

    对于从未接触过OSG的我来说,首先需要一个入门教程.在OSG论坛逛了半天,再加上google,最终决定使用<OSG程序设计>这本书. 下面就贴出书中的第一个例子:Hello World. ...

  7. turtle库应用实例2-六芒星的绘制

    六芒星的绘制 ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪ ...

  8. redux中间件的理解

    redux的中间件就是用来处理reducer和actions之间应用,常用的中间件有redux-thunk,redux-sage.在redux中通过applyMiddleware方法使用中间件 使用例 ...

  9. pycharm中的TODO注释用法

    pycharm 中可以在# 后面加TODO提示自己后续的开发动作. 点击pycharm又下角的小标签,会弹出一个列表,选择TODO选项. 进入TODO选项,可以看见所以设置的TODO,选择一个TODO ...

  10. SVN 报错问题

    svn: error: The subversion command line tools are no longer provided by Xcode ```. ## 问题分析 由于Mac绝大部分 ...