B - Finding Palindromes (字典树+manacher)
题目链接: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 ...
- 019(The XOR Largest Pair)(字典树)
题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1472 题目思路:异或是啥呀? 异或就是把两个数字变成位数相同的二进制在同位比较,相同为0,不同为 ...
随机推荐
- Linux管理用户和组
用户管理相关命令useradd 添加用户adduser 添加用户userdel 删除用户passwd 为用户设置密码usermod ...
- docker--Dockerfile--sonarqube
FROM openjdk:8 ENV SONAR_VERSION=6.7.1 \ SONARQUBE_HOME=/opt/sonarqube \ # Database configuration # ...
- BZOJ1212[HNOI2004]L语言——trie树+DP
题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...
- LOJ #6202. 叶氏筛法(min_25 筛)
题意 求 \([L, R]\) 之间的素数之和 . \(L≤10^{10},2×10^{10} \le R \le 10^{11}\) 题解 一个有点裸的 min_25筛 ? 现在我只会筛素数的前缀和 ...
- 机器学习工作流程第一步:如何用Python做数据准备?
这篇的内容是一系列针对在Python中从零开始运用机器学习能力工作流的辅导第一部分,覆盖了从小组开始的算法编程和其他相关工具.最终会成为一套手工制成的机器语言工作包.这次的内容会首先从数据准备开始. ...
- 启用SharePoint 2013文档版本控制
cls $PSSnapin = Add-PsSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue | Out-Nul ...
- LOJ [#115. 无源汇有上下界可行流](https://loj.ac/problem/115)
#115. 无源汇有上下界可行流 先扔个板子,上下界的东西一点点搞,写在奇怪的合集里面 Code: #include <cstdio> #include <cstring> # ...
- UVA 10480 Sabotage (网络流,最大流,最小割)
UVA 10480 Sabotage (网络流,最大流,最小割) Description The regime of a small but wealthy dictatorship has been ...
- 洛谷 P3956 棋盘(BFS)
传送门:Problem P3956 https://www.cnblogs.com/violet-acmer/p/9827010.html 题解: BFS 相关变量解释: color[maxn][ma ...
- 使用LTP套件对Linux系统进行压力测试
使用LTP套件对Linux系统进行压力测试 https://www.ubuntukylin.com/ukylin/forum.php?mod=viewthread&tid=6764 https ...