HDU 5421 Victor and String (回文自动机)
题目大意:让你维护一个字符串,支持在开头结尾插入字符,以及查询本质不同的回文串数量以及回文串总数量
开头结尾都维护一个$last$指针,如果插入新字符后,整个串是一个回文串,就把另一个$last$赋值成当前的$last$
为什么这样做就是正确的呢?
首先,对于这道题而言,一个回文串开头/结尾是等价的
不合并$last$的情况下,在当前方向添加字符不会被另一个方向所影响,就相当于只在末尾加字符
如果合并了$last$,说明现在另一个方向的开头字符,能和新添加的字符共同产生贡献,所以必须把另一个$last$赋值成当前的$last$,来完成都是在末尾新添加字符的“假象”
本质不同的回文串数量就是节点个数,回文串总数量就是所有节点在$pre$树中的深度总和*作为回文末尾的次数
每次$insert$时都更新即可,注意开$longlong$
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 200100
#define S1 (N1<<1)
#define ll long long
#define uint unsigned int
#define rint register int
#define dd double
#define il inline
#define inf 0x3f3f3f3f
#define idx(X) (X-'a')
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,L,R;
namespace PAM{
int trs[N1][],pre[N1],dep[N1],num[N1];
int lla,rla,tot;ll sum;
void init(){tot=lla=rla=,dep[]=-,pre[]=pre[]=;}
int lchk(char *str,int i,int p){return str[i+dep[p]+]!=str[i]?:;}
int rchk(char *str,int i,int p){return str[i-dep[p]-]!=str[i]?:;}
void Lins(char *str,int i)
{
int p=lla,np,fp,c=idx(str[i]);
while(lchk(str,i,p)) p=pre[p];
if(!trs[p][c])
{
np=++tot;
dep[np]=dep[p]+;
fp=pre[p];
while(lchk(str,i,fp)) fp=pre[fp];
pre[np]=trs[fp][c];
trs[p][c]=np;
num[np]=num[pre[np]]+;
}
lla=trs[p][c];
if(dep[trs[p][c]]==R-L+) rla=lla;
sum+=num[lla];
}
void Rins(char *str,int i)
{
int p=rla,np,fp,c=idx(str[i]);
while(rchk(str,i,p)) p=pre[p];
if(!trs[p][c])
{
np=++tot;
dep[np]=dep[p]+;
fp=pre[p];
while(rchk(str,i,fp)) fp=pre[fp];
pre[np]=trs[fp][c];
trs[p][c]=np;
num[np]=num[pre[np]]+;
}
rla=trs[p][c];
if(dep[trs[p][c]]==R-L+) lla=rla;
sum+=num[rla];
}
void clr()
{
tot++;
memset(trs,,tot**);
memset(pre,,tot*);
memset(dep,,tot*);
memset(num,,tot*);
tot=lla=rla=;sum=;
}
};
char str[N1]; int main()
{
//freopen("t2.in","r",stdin);
//freopen("a.out","w",stdout);
while(scanf("%d",&n)!=EOF)
{
int fl;L=,R=;
char tmp[];
PAM::clr(),PAM::init();
memset(str,,sizeof(str));
while(n--)
{
scanf("%d",&fl);
if(fl==){
scanf("%s",tmp);
str[--L]=tmp[];
PAM::Lins(str,L);
}else if(fl==){
scanf("%s",tmp);
str[++R]=tmp[];
PAM::Rins(str,R);
}else if(fl==){
printf("%d\n",PAM::tot-);
}else if(fl==){
printf("%lld\n",PAM::sum);
}
}
}
return ;
}
HDU 5421 Victor and String (回文自动机)的更多相关文章
- HDOJ 5421 Victor and String 回文串自己主动机
假设没有操作1,就是裸的回文串自己主动机...... 能够从头部插入字符的回文串自己主动机,维护两个last点就好了..... 当整个串都是回文串的时候把两个last统一一下 Victor and S ...
- hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash
题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...
- [2019杭电多校第二场][hdu6599]I Love Palindrome String(回文自动机&&hash)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6599 题目大意为求字符串S有多少个子串S[l,r]满足回文串的定义,并且S[l,(l+r)/2]也满足 ...
- HDU 5421 Victor and String(回文树)
Victor and String Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/262144 K (Java/Othe ...
- HDU 5421 Victor and String
Victor and String Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on HDU. Orig ...
- hdu5421 Victor and String 回文树(前后插入)
题目传送门 题意:对一个字符串支持四种操作,前插入字符,后插入字符,询问本质不同的回文串数量和所有回文串的数量. 思路: 就是在普通回文树的基础上,维护suf(最长回文后缀)的同时再维护一个pre(最 ...
- 回文树(回文自动机)(PAM)
第一个能看懂的论文:国家集训队2017论文集 这是我第一个自己理解的自动机(AC自动机不懂KMP硬背,SAM看不懂一堆引理定理硬背) 参考文献:2017国家集训队论文集 回文树及其应用 翁文涛 参考博 ...
- 2019 Multi-University Training Contest 2 I.I Love Palindrome String(回文自动机+字符串hash)
Problem Description You are given a string S=s1s2..s|S| containing only lowercase English letters. F ...
- 牛客多校第四场 I string 后缀自动机/回文自动机
这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...
随机推荐
- JQuery课堂学习笔记
第1课 JQuery技术简介 <%@ page language="java" import="java.util.*" pageEncoding=&qu ...
- sudo详细介绍
目录参数所在/etc/sudoers 1.Host_Alias定义主机别名 例:Host_Alias FILESERVERS = fs1,fs2 #注意“=”号两边要有空格隔开 ***由于现今li ...
- vue项目优化--使用CDN和Gzip
使用vue-cli构建的vue项目,在打包发布的时候,发现打包后的文件体积很大,使用webpack-bundle-analyzer分析后,发现占用空间最多的是引用的第三方依赖.第三方的依赖文件可以使用 ...
- ConcurrentHashMap 并发HashMap原理分析
ConcurrentHashMap和Hashtable主要区别就是围绕着锁的粒度以及如何锁.如图 左边便是Hashtable的实现方式---锁整个hash表:而右边则是Concurrent ...
- HDU 3306
先转一些 http://www.cnblogs.com/frog112111/archive/2013/05/19/3087648.html Fibonacci数列:F(0)=1 , F(1)=1 ...
- JavaScript AMD规范简单介绍(一)
AMD是"Asynchronous Module Definition"的缩写.意思就是"异步模块定义". AMD定义了我们所用的模块都是是异步载入的,所以我们 ...
- mysql设置远程訪问数据库的多种方法
问题:MySQL权限设置正确,但仍无法远程訪问.通过telnet发现3306port未打开. 分析:MySQL默认仅仅绑定127.0.0.1,即:仅仅有在本机才干訪问3306port. 解决:找到My ...
- ios-UI-汤姆猫德游戏实现
// // ViewController.m // UI-猜拳游戏 // // Created by jzq_mac on 15/7/15. // Copyright (c) 2015年 jz ...
- 百度编辑器图片在线流量返回url改动
百度编辑器中返回的是我们server中的url,有时并非我们须要的,比方图文编辑中.我想在线浏览上传过的图片 ,那么我返回的应该是腾讯server上面的url.这样才不会被腾讯的过滤器过来掉,全部我们 ...
- Swift - 获取应用名称、应用版本、设备型号、系统版本等信息
有时我们在 App 中提交一些统计信息或者用户反馈信息时,为了能更好地进行分析,通常会附带上当前应用程序的名称.版本号.设备型号.以及设备系统版本.下面演示如何获取这些信息. 1,效果图 程序启动后自 ...