poj3376 KMP+字典树求回文串数量(n*n)
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
aa aba aba abba baab
#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)的更多相关文章
- 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 ...
- 拓展KMP求回文串
题目:hdu3613: 题意:有26字母对应的价值,然后给出以个串,把它分成两段字串,如果字串是回文串,串的价值就是每个字符和,不是就为0.求最大价值. 博客 分析:拓展KMP的应用求回文字串. #i ...
- 2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对)
2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对) https://www.luogu.com.cn/problem/P5041 题意: 给一个字符串 \(S\) ,每 ...
- Palindrome - URAL - 1297(求回文串)
题目大意:RT 分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的. 线段数+后缀数组代码如下: ...
- manacher算法,求回文串
用来求字符串最长回文串或者回文串的总数量 #include<map> #include<queue> #include<stack> #include<cma ...
- 马拉车,O(n)求回文串
马拉车,O(n)求回文串 对整个马拉车算法步骤做个总结: 第一步:将每个原字母用两个特殊字符包围如: aaa --> #a#a#a# abab -->#a#b#a#b 同时可以由这个翻倍的 ...
- HDU 3613 Best Reward ( 拓展KMP求回文串 || Manacher )
题意 : 给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串,那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0.问 ...
- 3676: [Apio2014]回文串 求回文串长度与出现次数的最大值
「BZOJ3676」[Apio2014] 回文串 Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所 ...
- hdu 3294 manacher 求回文串
感谢: http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/ O(n)求给定字符串的以每个位置为中心的回文串长度. 中心思想:每次计算位 ...
随机推荐
- Scala教程之:PartialFunction
Scala中有一个很有用的traits叫PartialFunction,我看了下别人的翻译叫做偏函数,但是我觉得部分函数更加确切. 那么PartialFunction是做什么用的呢?简单点说Parti ...
- SpringBoot 集成Swagger2自动生成文档和导出成静态文件
目录 1. 简介 2. 集成Swagger2 2.1 导入Swagger库 2.2 配置Swagger基本信息 2.3 使用Swagger注解 2.4 文档效果图 3. 常用注解介绍 4. Swagg ...
- vue2.x学习笔记(二十八)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12682573.html. 生产环境部署 以下大多数内容在你使用vue cli的时候都是默认开启的,仅跟你自定义的构 ...
- HTML5 Canvas指纹及反追踪介绍
1 Canvas指纹的简介很多网站通过Canvas指纹来跟踪用户.browserleaks[1]是一个在线检测canvas指纹的网站.一般的指纹实现原理即通过canvas画布绘制一些图形,填写一些文字 ...
- linux 服务器/客户端 tcp通信的简单例子
昨天弄了sublime之后没有弄输入中文的了,学生党来着,刚好可以练练英语(英语渣渣,还要考六级),所以注释都写英文的(语法什么的就别太深究了) 服务器端: /*start from the very ...
- c++ concurrency
c++的并发涉及到这么几个东西: std::thread std::mutex std::lock_guard std::lock 参考资料: http://en.cppreference.com/w ...
- socket编程之并发回射服务器
使用到的函数: // 子进程返回0,父进程返回子进程ID,出错返回-1 pid_t fork(void); pid_t wait(int *wstatus); // 最常用的option是WNOHAN ...
- CentOS安装配置nginx和php
今天买了台阿里云服务器用于日常开发测试(新人9块钱半年).系统版本CentOS 6.5 64位. 首先安装nginx: yum install nginx 参考文档: 在CentOS 6上搭建LNMP ...
- Web框架,Hibernate向数据库插入数据,数据库没有值怎么办?
用web框架技术,使用Hibernate向数据库添加信息,控制台显示插入成功的语句,可是数据库却没有值:错误如下: (1)不要自己创建数据库!!,Web框架可以自己自动生成,自己创建可能会报错! (2 ...
- python学习之如何一次性输出多个变量的值
如果要输出多个结果 ,中间使用逗号隔开,且引用变量为%(变量1,变量2,变量3)例如