题目大意:有 N 个字符串,所有的字符串长度不超过 200W 任意俩俩字符串可以自由组合,问组合的字符串是回文串的个数有多少个?
 
分析:这是一个相当猥琐的字符串处理,因为没有说单个的字符串最少多长,所以很可能会有这样的情况,200w个字符串,每个字符串长度1,或者1个串,这个串的长度是100w, 为了对付这种猥琐的方式可以用一个长为100w的字符串保存所有的串,然后用另一个数组记录每个字符串所在的区间。匹配的时候可以使用trie因为回文串是两端匹配,所以插入trie的时候可以倒着插入,不过查询的时候会出现两种情况,一种是这个字符串已经匹配完,不过他后面匹配的字符串没有完,另一种是这个字符串匹配完还有剩余长度,不管哪种情况都需要判断一下剩余的串是否是回文串,tire里面的保存后缀,匹配串保存的是前缀。
 
代码如下:
================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN = 2e6+;
const int oo = 1e9+; struct Trie
{///字典树的节点
int next[];
int leaf;///以这个节点为终点的叶子节点个数
int count;///后面回文串的数量 void Free()
{
leaf = count = ;
memset(next, false, sizeof(next));
} }trie[MAXN]; int top;///配合字典树使用,top表示没有使用的内存
int start[MAXN], p[MAXN<<];
char MumStr[MAXN], Estr[MAXN<<];
bool suffix[MAXN];///后缀是否是回文串
bool prefix[MAXN];///前缀是否是回文串 void BuildTrie(int n)
{
int p = ; for(int i=start[n+]-; i>=start[n]; i--)
{///把字符串倒插进去
int k = MumStr[i] - 'a'; trie[p].count += prefix[i]; if(trie[p].next[k] == )
{
trie[p].next[k] = ++top;
trie[top].Free();
}
p = trie[p].next[k];
} trie[p].leaf += ;
}
void Manacher(int n)
{
int i, id=, len=; Estr[] = '$'; for(i=start[n]; i<start[n+]; i++)
{
Estr[len++] = '#';
Estr[len++] = MumStr[i]; suffix[i] = false;
prefix[i] = false;
}
Estr[len] = '#';
Estr[len+] = ; for(i=; i<len; i++)
{
p[i] = ; if(p[id]+id > i)
p[i] = min(p[id*-i], p[id]+id-i); while(Estr[ i+p[i] ] == Estr[ i-p[i] ])
p[i]++; if(p[id]+id < p[i]+i)
id = i; if(p[i] == i)
prefix[ start[n]+p[i]- ] = true;
if(p[i]+i- == len)
suffix[ start[n+]-p[i]+ ] = true;
}
}
int Query(int n)
{
int i, p=, sum = ; for(i=start[n]; i<start[n+]; i++)
{
int k = MumStr[i] - 'a'; if(trie[p].next[k] == )
break; p = trie[p].next[k]; if(suffix[i+] || i==start[n+]-)
sum += trie[p].leaf;
} if(i == start[n+])
sum += trie[p].count; return sum;
} int main()
{
int N; while(scanf("%d", &N) != EOF)
{
int i, len; top = ;
trie[].Free(); for(i=; i<=N; i++)
{
scanf("%d%s", &len, MumStr+start[i]);
start[i+] = start[i] + len; Manacher(i);
BuildTrie(i);
} long long ans = ; for(i=; i<=N; i++)
ans += Query(i); printf("%lld\n", ans);
} return ;
}
/**
2
3 abc
4 acba */

Finding Palindromes - 猥琐的字符串(Manacher+trie)的更多相关文章

  1. POJ 3376 Finding Palindromes(manacher求前后缀回文串+trie)

    题目链接:http://poj.org/problem?id=3376 题目大意:给你n个字符串,这n个字符串可以两两组合形成n*n个字符串,求这些字符串中有几个是回文串. 解题思路:思路参考了这里: ...

  2. poj3376 Finding Palindromes【exKMP】【Trie】

    Finding Palindromes Time Limit: 10000MS   Memory Limit: 262144K Total Submissions:4710   Accepted: 8 ...

  3. POJ3376 Finding Palindromes —— 扩展KMP + Trie树

    题目链接:https://vjudge.net/problem/POJ-3376 Finding Palindromes Time Limit: 10000MS   Memory Limit: 262 ...

  4. POJ 3376 Finding Palindromes(扩展kmp+trie)

    题目链接:http://poj.org/problem?id=3376 题意:给你n个字符串m1.m2.m3...mn 求S = mimj(1=<i,j<=n)是回文串的数量 思路:我们考 ...

  5. poj 3376 Finding Palindromes

    Finding Palindromes http://poj.org/problem?id=3376 Time Limit: 10000MS   Memory Limit: 262144K       ...

  6. PHP后门新玩法:一款猥琐的PHP后门分析

    0x00 背景 近日,360网站卫士安全团队近期捕获一个基于PHP实现的webshell样本,其巧妙的代码动态生成方式,猥琐的自身页面伪装手法,让我们在分析这个样本的过程中感受到相当多的乐趣.接下来就 ...

  7. 模板—字符串—Manacher

    模板—字符串—Manacher Code: #include <cstdio> #include <cstring> #include <algorithm> us ...

  8. delphi之猥琐的webserver实现

    http://www.birdol.com/cainiaobiancheng/238.html delphi之猥琐的webserver实现 菜鸟编程  十五楼的鸟儿  7年前 (2009-01-01) ...

  9. 牛客练习赛11 假的字符串 (Trie树+拓扑找环)

    牛客练习赛11 假的字符串 (Trie树+拓扑找环) 链接:https://ac.nowcoder.com/acm/problem/15049 来源:牛客网 给定n个字符串,互不相等,你可以任意指定字 ...

随机推荐

  1. 实现HTTP跳转到HTTPS

    1 首先在您的网站下新建一个站点,名称随意,在属性中分配TCP端口为80,SSL不分配 然后在属性>主目录下配置 将此资源的内容来自: 改为 重定向到URL 然后重定向到中  输入:  HTTP ...

  2. while read line无法循环read文件

    while read line 与for循环的区别 例子:要从一个ip列表中获取ip.port,然后ssh ip 到目标机器进行特定的command操作ssh -o StrictHostKeyChec ...

  3. iOS中MVVM的架构设计与团队协作

    对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架,之前用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人 ...

  4. CDH5 集群安装教程

    一.虚拟机的安装和网络配置. 1.虚拟机安装. 2.安装CentOS-6.5 64位版本. 桥接模式: Master: 内存:3G: 硬盘容量40G: 4核: Slave: 内存2G: 硬盘容量30G ...

  5. 用response输出一个验证码

    package servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Servle ...

  6. 16_用LVM扩展xfs文件系统(当分区空间不够时)

    1. 查看当前卷组空间(volume group)使用情况 [root@localhost ~]# vgdisplay 从下面的代码中发现剩余空间为0 --- Volume group --- VG ...

  7. 单选按钮 点击value值自动把单选按钮选中

    HTML 代码 <tr>       <td align="right">性别:</td>       <td><inputt ...

  8. Bootstrap_表单_图标

    在Bootstrap框架中是通过给元素添加“glyphicon”类名来实现,然后通过伪元素“:before”的“content”属性调取对应的icon编码: <span class=" ...

  9. WIN10 搜索功能无法搜索本地应用

    原因是使用360卫士此类软件把windows search 服务给禁掉了. 解决方案很简单,就是把windows search 服务重新设置成自启动,并立刻启动,就ok了. 至于如何打开服务组件,可以 ...

  10. 利用sfntly的sfnttool.jar提取中文字体

    雨忆博客中提到了sfntly(具体介绍可以看:https://code.google.com/p/sfntly/),利用其中sfnttool.jar就可以提取只包含指定字符的字体,如果想在页面中通过@ ...