POJ 3376 Finding Palindromes(manacher求前后缀回文串+trie)
题目链接:http://poj.org/problem?id=3376
题目大意:给你n个字符串,这n个字符串可以两两组合形成n*n个字符串,求这些字符串中有几个是回文串。
解题思路:思路参考了这里:http://blog.csdn.net/qq_30241305/article/details/50718051
做法:首先由两个字符串A,B.要使它们能组成回文串有三种情况
情况① :alen < blen
abc abacba abcaba
A B RB
如上所示,A是B的反串前缀,且b的剩余部分可以认为是后缀是回文串
情况②:alen > blen
abcaba cba abc
A B RB
B的反串是A的前缀,且a的后缀是回文串
情况③:alen == blen
b是a的反串,这个就不用解释了吧。
现将所有正序字符(原字符串)串建立在字典树中。然后用反串去匹配,根据上面给出的三种情况作出判断。
另外:因为只给了字符串的总长度,所以,只开一维的字符串数组,每次接着上次字符串结束的位置开始即可。为了方便,记录字符串开始的位置,和结束的位置。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=2e6+; LL ans;
int n,len1,len2,idx,root;
char s[N],str[N*];
int trie[N][],p[N*],End[N],hou[N];//End[i]表示以节点i为结尾的字符串的数目
//hou[i]表示节点i之后(不包括i)的后缀回文串数目 struct node{
int st,len;
}a[N]; void init(){
str[]='$';
str[]='#';
len1--;
for(int i=;i<=len1;i++){
str[i*]=s[i];
str[i*+]='#';
}
len2=len1*+;
str[len2]='@';
} void manacher(){
init();
int id=-,mx=-;
for(int i=;i<len2;i++){
if(mx>i) p[i]=min(p[id*-i],mx-i);
else p[i]=;
while(str[i-p[i]]==str[i+p[i]])
p[i]++;
if(i+p[i]>mx){
mx=i+p[i];
id=i;
}
}
} //将字符串正序插入字典树中
void Insert(){
for(int i=;i<n;i++){
int now=root;
for(int j=a[i].st;j<a[i].st+a[i].len;j++){
if(!trie[now][s[j]-'a']) trie[now][s[j]-'a']=++idx;
now=trie[now][s[j]-'a'];
int mid=((j+)*-+(a[i].st+a[i].len-)*+)/;//(j+1)*2是s[j+1]对应str的位置(j+1)*2-1则是边缘的'#',同理(a[i].st+a[i].len-1)*2+1也对应边缘'#'
if(p[mid]>mid-(j+)*+)
hou[now]++;
}
hou[now]--; //因为字符串末尾的"#"也算成一个回文串了,所以要减掉
End[now]++;
}
} //计算可以生成的回文串数
void Find(){
for(int i=;i<n;i++){
int now=root;
for(int j=a[i].st+a[i].len-;j>=a[i].st;j--){
//匹配失败,没有对应的字符串
if(!trie[now][s[j]-'a']){
now=-;
break;
}
now=trie[now][s[j]-'a'];
if(End[now]){ //情况①或③
int mid=(a[i].st*-+(j-)*+)/;
if(p[mid]>mid-a[i].st*+)
ans+=End[now];
}
}
if(now!=-) ans+=hou[now]; //情况②
}
} int main(){
while(~scanf("%d",&n)){
idx=,len1=,ans=;
memset(trie,,sizeof(trie));
memset(End,,sizeof(End));
memset(hou,,sizeof(hou));
for(int i=;i<n;i++){
scanf("%d",&a[i].len);
scanf("%s",s+len1);
a[i].st=len1;
len1+=a[i].len;
}
manacher();
Insert();
Find();
printf("%lld\n",ans);
}
return ;
}
POJ 3376 Finding Palindromes(manacher求前后缀回文串+trie)的更多相关文章
- HDU 3613 Best Reward(扩展KMP求前后缀回文串)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分割 ...
- POJ - 3376 Finding Palindromes manacher+字典树
题意 给n个字符串,两两拼接,问拼接后的\(n\times n\)个字符串中有多少个回文串. 分析 将所有正串插入字典树中,马拉车跑出所有串哪些前缀和后缀为回文串,记录位置,用反串去字典树中查询,两字 ...
- POJ 3376 Finding Palindromes (tire树+扩展kmp)
很不错的一个题(注意string会超时) 题意:给你n串字符串,问你两两匹配形成n*n串字符串中有多少个回文串 题解:我们首先需要想到多串字符串存储需要trie树(关键),然后我们正序插入倒序匹配就可 ...
- Manacher算法 - 求最长回文串的利器
求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...
- Manacher(最长镜面回文串)
I - O'My! Gym - 101350I Note: this is a harder version of Mirrored string I. The gorillas have recen ...
- poj 3376 Finding Palindromes
Finding Palindromes http://poj.org/problem?id=3376 Time Limit: 10000MS Memory Limit: 262144K ...
- POJ 3376 Finding Palindromes(扩展kmp+trie)
题目链接:http://poj.org/problem?id=3376 题意:给你n个字符串m1.m2.m3...mn 求S = mimj(1=<i,j<=n)是回文串的数量 思路:我们考 ...
- POJ - 3376 Finding Palindromes(拓展kmp+trie)
传送门:POJ - 3376 题意:给你n个字符串,两两结合,问有多少个是回文的: 题解:这个题真的恶心,我直接经历了5种错误类型 : ) ... 因为卡内存,所以又把字典树改成了指针版本的. 字符串 ...
- HDU 3613 Best Reward(manacher求前、后缀回文串)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 题目大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分 ...
随机推荐
- 目标检测应用化之web页面(YOLO、SSD等)
在caffe源码目录下的examples下面有个web_demo演示代码,其使用python搭建了Flask web服务器进行ImageNet图像分类的演示. 首先安装python的依赖库:pip i ...
- Tensorflow Object_Detection 目标检测 笔记
Tensorflow models Code:https://github.com/tensorflow/models 编写时间:2017.7 记录在使用Object_Detection 中遇到的问题 ...
- Chapter4(表达式) --C++Prime笔记
1.重载运算符:为已经存在的运算符赋予另外一层含义. 2.左值与右值: ①当一个对象被用作右值的时候,用的是对象的值(内容):当一个对象被用作左值的时候,用的是对象的身份(在内存中的位置). ②在 ...
- 利用Confluence搭建企业Wiki
Confluence安装与部署 下载安装包及破解包 安装包下载地址:https://www.atlassian.com/software/confluence/download-archives 破解 ...
- RACCommand
RACCommand是ReactiveCocoa中用于表示UI操作的一个类.它包含一个代表了UI操作的结果的信号以及标识操作当前是否被执行的一个状态. 1.创建新的RACCommand self.ex ...
- 安装并使用 Wowza 发布你的 RTMP 直播流
转载自:http://blog.csdn.net/defonds/article/details/11979095 I. 下载 Wowza 官方下载地址 http://www.wowz ...
- bzoj千题计划125:bzoj1037: [ZJOI2008]生日聚会Party
http://www.lydsy.com/JudgeOnline/problem.php?id=1037 一个区间是否满足 任意连续的一段,男孩与女孩的数目之差不超过k, 取决于男孩与女孩数目之差的最 ...
- 第八届蓝桥杯c/c++省赛题目整理
第一题 标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都 ...
- Zabbix监控PV和UV
Zabbix-server:172.21.97.153 Zabbix-agent(Nginx):172.17.27.61 # Nginx日志如下: # head -3 Syz.access.log w ...
- Elasticsearch技术解析与实战(二)文档的CRUD操作
启动Elasticsearch和kibana 访问Elasticsearch:http://localhost:9200/?pretty 访问kibana:http://localhost:5601 ...