题目链接:https://cn.vjudge.net/contest/283743#problem/B
题目大意:给你n个字符串,然后问你将这位n个字符串任意两两组合,然后问你这所有的n*n种情况中,是回文串的有多少个?
题目大意:学到了一个很骚气的存储多个零散字符串的方法,因为有可能个给你很多零散的字符串,我们可以将这些字符串存储在一个字符串里面,然后再额外加一个数组记录每一个字符串的开始位置和截止位置就好了。 然后是对于这个题,首先说一下判断字符串的方法,对于每一个字符串我们通过manacher算法求出每一个点的最长的回文串,然后在字典树中反序存储这个字符串。
举个例子:aaba和baa,这个时候baa插在aaba后面是可以构成回文串的,在字典树中baa是倒序存储的,所以就能够和aaba的前缀aab相匹配,然后我们在看aab后面的子串是不是回文串,如果是回文串的话,这个两个就能够形成回文串,因为前面部分和后面部分是对称的,并且中间部分也是回文串。
我们对于每一个字符串,
surf[i]记录的是对于当前的字符串,从第i+1个位置开始,能不能构成字符串。
pre[i]数组记录的是对于当前的字符串,从当前字符串的第一个位置开始到第i-1个位置,前缀能不能构成回文串。
val[i]数组记录的是字典树中从第0个位置到i所形成的的字符串的个数。
qian[i]数组记录的是当前节点后面是回文串的数目。
查询的时候,一共有两种情况:
一种是题目中说的aaba和bba这种情况,到了某一个字符串的位置之后,这个位置之前的有对称的字符串,这个位置之后的是一个回文串。
另一种是一个字符串是回文串,一直到底部都是能构成回文串的,这个时候还应该加上一直到这个字符串底部的回文串的个数就可以了。
每一次查询当前节点后面是不是回文串,如果是的话就加上这个字符串的个数。如果找到了底部还需要注意后面形成的回文串的个数。
AC代码:
#include<iostream>
#include<stack>
#include<iomanip>
#include<cmath>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
# define ll long long
const int maxn = 2e6+;
const int maxm= 2e6+;
char str[maxn],tmp[maxn<<];
bool pre[maxn],suf[maxn];
int pp[maxn<<],tot;
int qian[maxn],val[maxn];
int start[maxn];
int ch[maxn][];
void init()
{
for(int i=; i<=tot; i++)
{
qian[i]=,val[i]=;
for(int j=; j<; j++)
{
ch[i][j]=;
}
}
tot=;
}
void trie(int t)
{
int p=;
for(int i=start[t+]-; i>=start[t]; i--)
{
int tmp=str[i]-'a';
qian[p]+=pre[i];
if(!ch[p][tmp])
ch[p][tmp]=++tot;
p=ch[p][tmp];
}
val[p]+=;
}
void manacher(int n)
{
int i,mx=,len=,id=;
tmp[]='$';
for(i=start[n]; i<start[n+]; i++)
{
tmp[len++]='#';
tmp[len++]=str[i];
pre[i]=;
suf[i]=;
}
tmp[len]='#';
tmp[len+]=;
for(int i=; i<len; i++)
{
pp[i] = ;
if(pp[id]+id > i)
pp[i] = min(pp[id*-i], pp[id]+id-i);
while(tmp[ i+pp[i] ] == tmp[ i-pp[i] ])
pp[i]++;
if(pp[id]+id < pp[i]+i)
id = i;
if(pp[i]==i)
pre[start[n]+pp[i]-]=;
if(i+pp[i]-==len)
suf[start[n+]-pp[i]+]=;
}
}
ll query(int t)
{
ll sum=;
int p=,i;
for( i=start[t]; i<start[t+]; i++)
{
int tmp=str[i]-'a';
if(ch[p][tmp]==)
break;
p=ch[p][tmp];
if(suf[i+]==||i+==start[t+])
sum+=val[p];
}
if(i==start[t+])
sum+=qian[p];
return sum;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
init();
int len;
for(int i=; i<=n; i++)
{
scanf("%d%s",&len,str+start[i]);
start[i+]=start[i]+len;
manacher(i);
trie(i);
}
ll ans=;
for(int i=; i<=n; i++)
{
ans+=query(i);
}
printf("%lld\n",ans);
}
return ;
}
B - Finding Palindromes (字典树+manacher)的更多相关文章
-
POJ 3376 Finding Palindromes EX-KMP+字典树
题意: 给你n个串串,每个串串可以选择和n个字符串拼接(可以自己和自己拼接),问有多少个拼接后的字符串是回文. 所有的串串长度不超过2e6: 题解: 这题由于是在POJ上,所以string也用不了,会 ...
-
Finding Palindromes - 猥琐的字符串(Manacher+trie)
题目大意:有 N 个字符串,所有的字符串长度不超过 200W 任意俩俩字符串可以*组合,问组合的字符串是回文串的个数有多少个? 分析:这是一个相当猥琐的字符串处理,因为没有说单个的字符串最少多长 ...
-
POJ3376 Finding Palindromes —— 扩展KMP + Trie树
题目链接:https://vjudge.net/problem/POJ-3376 Finding Palindromes Time Limit: 10000MS Memory Limit: 262 ...
-
poj3376 Finding Palindromes【exKMP】【Trie】
Finding Palindromes Time Limit: 10000MS Memory Limit: 262144K Total Submissions:4710 Accepted: 8 ...
-
字典树 - A Poet Computer
The ACM team is working on an AI project called (Eih Eye Three) that allows computers to write poems ...
-
ACM: Gym 100935F A Poet Computer - 字典树
Gym 100935F A Poet Computer Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d &am ...
-
Trie树(字典树)(1)
Trie树.又称字典树,单词查找树或者前缀树,是一种用于高速检索的多叉树结构. Trie树与二叉搜索树不同,键不是直接保存在节点中,而是由节点在树中的位置决定. 一个节点的全部子孙都有同样的前缀(pr ...
-
poj 3376 Finding Palindromes
Finding Palindromes http://poj.org/problem?id=3376 Time Limit: 10000MS Memory Limit: 262144K ...
-
萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
随机推荐
-
MapReduce编程job概念原理
在Hadoop中,每个MapReduce任务都被初始化为一个job,每个job又可分为两个阶段:map阶段和reduce阶段.这两个阶段分别用两个函数来表示.Map函数接收一个<key,valu ...
-
leetcode96 Unique Binary Search Trees
题目: Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For e ...
-
oracle个人总结
oracle优化原则 1:insert 插入 (1):insert into /*+ append */ NOLOGGING 2: select 查询 (1):/*+ full(v) */ 全表查询 ...
-
word2vec浅析
本文是參考神经网络语言模型.word2vec相关论文和网上博客等资料整理的学习笔记.仅记录 自己的学习历程,欢迎拍砖. word2vec是2013年google提出的一种神经网络的语言模型,通过神经网 ...
-
插入排序算法java
转自https://blog.csdn.net/jianyuerensheng/article/details/51254415 1.基本思想 直接插入排序的基本操作是将一个记录插入到已经排好的有序表 ...
-
安装kafka过程及出现的问题解决
第一步:下载kafka安装包 下载地址:http://kafka.apache.org/downloads 解压 到/usr/local 目录 tar -zxvf kafka_2.12-2.2.0 第 ...
-
MATLAB indexing question
Question: I have a matrix, for example A = [ 1 2 3; 4 5 6; 7 8 9] ; and a vector of size 1x3 which s ...
-
Linux修改/etc/profile配置错误command is not found自救方法
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
-
Grid Search学习
转自:https://www.cnblogs.com/ysugyl/p/8711205.html Grid Search:一种调参手段:穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性 ...
-
Thinking in java note1
Part information collecting from http://blog.csdn.net/leonliu06/article/details/78638841 1. 如果已经定义了一 ...