poj3376 Finding Palindromes【exKMP】【Trie】
| Time Limit: 10000MS | Memory Limit: 262144K | |
| Total Submissions:4710 | Accepted: 879 | |
| 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
Source
#include<iostream>
//#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
//#include<cstdlib>
#include<cstring>
#include<algorithm>
//#include<queue>
#include<vector>
//#include<set>
//#include<climits>
//#include<map>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
#define N 100010
#define pi 3.1415926535
#define inf 0x3f3f3f3f const int maxn = 2e6 + ;
int n, sum_len;
char s[maxn], s_rev[maxn];
int st[maxn], ed[maxn]; int nxt[maxn], ex[maxn];
bool flag[][maxn];
void GETNEXT(char *str, int l, int r)
{
int i=l,j,po;
nxt[i]=r - l + ;//初始化next[0]
while(str[i]==str[i+]&&i<=r)//计算next[1]
i++;
nxt[l + ]=i - l;
po= + l;//初始化po的位置
for(i=+l;i<=r;i++)
{
if(nxt[i-po + l]+i - l<nxt[po]+po - l)//第一种情况,可以直接得到next[i]的值
nxt[i]=nxt[i-po + l];
else//第二种情况,要继续匹配才能得到next[i]的值
{
j=nxt[po]+po-i;
if(j<)j=;//如果i>po+next[po],则要从头开始匹配
while(i+j<=r&&str[l+j]==str[j+i])//计算next[i]
j++;
nxt[i]=j;
po=i;//更新po的位置
}
}
}
//计算extend数组
void EXKMP(char *s1,char *s2, int l, int r, int sign)
{
int i=l,j,po;
GETNEXT(s2, l, r);//计算子串的next数组
//for(j = l; j <= r; j++)cout<<nxt[j]<<endl;
while(s1[i]==s2[i]&&i<=r)//计算ex[0]
i++;
ex[l]=i - l;
po=l;//初始化po的位置
for(i=l + ;i<=r;i++)
{
if(nxt[i-po + l]+i - l<ex[po]+po -l)//第一种情况,直接可以得到ex[i]的值
ex[i]=nxt[i-po+l];
else//第二种情况,要继续匹配才能得到ex[i]的值
{
j=ex[po]+po-i;
if(j<)j=;//如果i>ex[po]+po则要从头开始匹配
while(i+j<=r&&s1[j+i]==s2[l+j])//计算ex[i]
j++;
ex[i]=j;
po=i;//更新po的位置
}
}
for(int i = l; i <= r; i++){
//cout<<ex[i]<<endl;
if(ex[i] == r - i + ){
flag[sign][i] = true;
}
}
} struct Trie{
int trie[maxn][];
int cnt[maxn];
int val[maxn];
int tot;
}tr; void init()
{
memset(flag, , sizeof(flag));
memset(nxt, , sizeof(nxt));
memset(ex, , sizeof(ex));
for(int i = ; i <= tr.tot; i++){
memset(tr.trie[i], , sizeof(tr.trie[i]));
tr.cnt[i] = ;
tr.val[i] = ;
}
tr.tot = ;
} void insertt(char *str, int l, int r)
{
int p = ;
for(int k = l; k <= r; k++){
int ch = str[k] - 'a';
tr.val[p] += flag[][k];
if(tr.trie[p][ch] == ){
tr.trie[p][ch] = ++tr.tot;
}
p = tr.trie[p][ch]; }
tr.cnt[p]++;
} LL searchh(char *str, int l, int r)
{
LL ans = ;
int p = ;
for(int k = l; k <= r; k++){
//cout<<flag[k]<<endl;
int ch = str[k] - 'a';
p = tr.trie[p][ch];
if(p == )break;
if(k < r && flag[][k + ] || k == r)ans += tr.cnt[p];
}
if(p)ans += tr.val[p];
//ans += tr.cnt[p];
return ans;
} int main()
{
while(scanf("%d", &n) != EOF){
sum_len = ;
init();
for(int i = ; i < n; i++){
int l;
scanf("%d %s", &l, s + sum_len);
for(int j = ; j < l; j++){
s_rev[sum_len + j] = s[sum_len + l - - j];
}
st[i] = sum_len;
sum_len += l;
ed[i] = sum_len - ; EXKMP(s, s_rev, st[i], ed[i], );
EXKMP(s_rev, s, st[i], ed[i], );
insertt(s, st[i], ed[i]);
} LL ans = ;
/*for(int i = 0; i < sum_len; i++){
cout<<s[i]<<" "<<flag[0][i]<<" "<<flag[1][i]<<endl;
}*/
//cout<<s<<endl;
for(int i = ; i < n; i++){
ans += searchh(s_rev, st[i], ed[i]);
}
printf("%lld\n", ans);
}
return ;
}
poj3376 Finding Palindromes【exKMP】【Trie】的更多相关文章
- POJ3376 Finding Palindromes —— 扩展KMP + Trie树
题目链接:https://vjudge.net/problem/POJ-3376 Finding Palindromes Time Limit: 10000MS Memory Limit: 262 ...
- 【BZOJ2741】【FOTILE模拟赛】L 分块+可持久化Trie树
[BZOJ2741][FOTILE模拟赛]L Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max( ...
- 【hiho一下 第四周】Trie图
[题目链接]:http://hihocoder.com/problemset/problem/1036?sid=1092555 [题意] [题解] AC自动机的模板题; 在求有没有子串的时候; 注意要 ...
- 【hiho一下第二周 】Trie树
[题目链接]:http://hihocoder.com/problemset/problem/1014 [题意] [题解] 在字典树的域里面加一个信息cnt; 表示这个节点下面,记录有多少个单词; 在 ...
- 【spring源码分析】IOC容器初始化(二)
前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...
- 「洛谷5283」「LOJ3048」「十二省联考2019」异或粽子【可持久化01trie+优先队列】
题目链接 [洛谷传送门] [LOJ传送门] 题目大意 让你求区间异或和前\(k\)大的异或和的和. 正解 这道题目是Blue sky大佬教我做的(祝贺bluesky大佬进HA省A队) 我们做过某一些题 ...
- 【codeforces】【比赛题解】#855 Codefest 17
神秘比赛,以<哈利波特>为主题……有点难. C题我熬夜切终于是写出来了,可惜比赛结束了,气啊. 比赛链接:点我. [A]汤姆·里德尔的日记 题意: 哈利波特正在摧毁神秘人的分灵体(魂器). ...
- 【BZOJ】【2434】【NOI2011】阿狸的打字机
AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...
- 【洛谷5439】【XR-2】永恒(树链剖分,线段树)
[洛谷5439][XR-2]永恒(树链剖分,线段树) 题面 洛谷 题解 首先两个点的\(LCP\)就是\(Trie\)树上的\(LCA\)的深度. 考虑一对点的贡献,如果这两个点不具有祖先关系,那么这 ...
随机推荐
- 数据库连接池优化配置(druid,dbcp,c3p0)
主要描述了数据库连接池参数配置的准则,针对常用的数据库连接池(c3p0,dbcp,druid)给出推荐的配置. 考虑因素 1:当前连接DB的规模 2:并发情况 3:执行db的响应时间 配置考虑 1 ...
- TerminateProcess的使用问题
最好时外部进程来结束目标进程,类似于任务管理器的结束目标进程方式.如果是自身进程想结束自身,可能不同版本的windows行为不一致,有一些能自身强制退出,有一些强制退出不了. 本来MSDN上就说了这个 ...
- 如何在WCF中用TcpTrace工具查看发送和接收的SOAP消息
WCF对消息加密(只对消息加密,不考虑Authorize)其实很简单,只要在server和client端的binding加入security mode为Message(还有Transport, Tra ...
- mark 阿里支付
开源软件企业版特惠高校版博客 我的码云 ·· 8月18日(周六)成都源创会火热报名中,四位一线行业大牛与你面对面,探讨区块链技术热潮下的冷思考. 开源项目 > WEB应用开发 > Web开 ...
- Cacti 1.1.6 添加monitor和thold插件
以前一直使用0.8版本的cacti,最近升级到1.1.6之后,发现以前0.8用的插件已经不适用了,需要下载新的插件包进行导入到下面网址获取Cacti插件包https://github.com/Cact ...
- Latex学习(一)
要在整个系统中使用TEX Live的字体(假定你有足够的权限),请依照下面的步骤来做: 1.将texlive-fontconfig.conf文件复制到/etc/fonts/conf.d/09-texl ...
- MXNET:多层感知机
从零开始 前面了解了多层感知机的原理,我们来实现一个多层感知机. # -*- coding: utf-8 -*- from mxnet import init from mxnet import nd ...
- 前台报错:Uncaught TypeError: Cannot read property '0' of null
错误现象: var div1=mycss[0].style.backgroundColor; //这一行提示360和chrome提示:Uncaught TypeError: Cannot read ...
- csharp中DateTime总结-转
Table of Contents 1 时间格式输出 2 求某天是星期几 3 字符串转换为DateTime 3.1 String->DateTime 的弹性做法 4 计算2个日期之间的天数差 5 ...
- Spark学习笔记——构建分类模型
Spark中常见的三种分类模型:线性模型.决策树和朴素贝叶斯模型. 线性模型,简单而且相对容易扩展到非常大的数据集:线性模型又可以分成:1.逻辑回归:2.线性支持向量机 决策树是一个强大的非线性技术, ...