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. Spring5参考指南:事件Event

    文章目录 基于继承的Event 基于注解的Event 异步侦听器 Spring提供了很方便的事件的处理机制,包括事件类ApplicationEvent和事件监听类ApplicationListener ...

  2. rabbitMQ安装docker版 /权限管理命令

    1.进入docker hub镜像仓库地址:https://hub.docker.com/ 2.搜素rabbitMQ 查询镜像,可以看到多种类型,选择带有web页面的(managment) 3.拉取镜像 ...

  3. js中的filter

    filter是常说的增删改查中的'查',当对一个数组进行筛选时,经常会使用indexOf 和es6中的includes()方法.filter是es5中的一种迭代方法,其定义为:对数组中的每一项运行给定 ...

  4. 解决vue中BMap未定义问题

    原文链接: 点我 最近在项目中使用了百度地图来显示物流信息,实现方式有两种: 引用Vue Baidu Map引用BMap存在的问题:\color{red}{存在的问题:}存在的问题::使用BMap可以 ...

  5. vue无法自动打开浏览器

    原文链接: 点我 如果不能自动打开浏览器,是因为没有安装插件. 插件安装的方法1.安装插件,在cmd中输入: $ npm i open-browser-webpack-plugin --save这里的 ...

  6. 数学--数论--HDU 5382 GCD?LCM?(详细推导,不懂打我)

    Describtion First we define: (1) lcm(a,b), the least common multiple of two integers a and b, is the ...

  7. 不可错过的java面试博客之java集合篇

    1. List List 是有序的 Collection.Java List 一共三个实现类: 分别是 ArrayList.Vector 和 LinkedList ArrayList ArrayLis ...

  8. 【Hadoop离线基础总结】完全分布式环境搭建

    完全分布式环境搭建 服务规划 适用于工作当中正式环境搭建 安装步骤 第一步:安装包解压 停止之前的Hadoop集群的所有服务,并删除所有机器的Hadoop安装包,然后重新解压Hadoop压缩包 三台机 ...

  9. 超简单笔记本改造nas--一个萌新的摸爬滚打

    最近好久没更新,你们有没有想我啊(手动滑稽)咳咳,言归正传,如同标题,最近闲来无事,打算利用家里的闲置笔记本电脑搭建一个nas.**注意:本文不涉及群晖以及相关专业NAS服务供应商!!!**nas分两 ...

  10. Excel心得

    智能表.数据透视表.分类汇总表是Excel最值得学的技能. 通过插入表,或者快捷键Ctrl+T/Ctrl+L,可以将区域转换为智能表,保证了字段的公式的统一,而且版式自动化处理,一深一浅.Ctrl+Q ...