题目大意:让你维护一个字符串,支持在开头结尾插入字符,以及查询本质不同的回文串数量以及回文串总数量

开头结尾都维护一个$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 (回文自动机)的更多相关文章

  1. HDOJ 5421 Victor and String 回文串自己主动机

    假设没有操作1,就是裸的回文串自己主动机...... 能够从头部插入字符的回文串自己主动机,维护两个last点就好了..... 当整个串都是回文串的时候把两个last统一一下 Victor and S ...

  2. hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash

    题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...

  3. [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]也满足 ...

  4. HDU 5421 Victor and String(回文树)

    Victor and String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/262144 K (Java/Othe ...

  5. HDU 5421 Victor and String

    Victor and String Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on HDU. Orig ...

  6. hdu5421 Victor and String 回文树(前后插入)

    题目传送门 题意:对一个字符串支持四种操作,前插入字符,后插入字符,询问本质不同的回文串数量和所有回文串的数量. 思路: 就是在普通回文树的基础上,维护suf(最长回文后缀)的同时再维护一个pre(最 ...

  7. 回文树(回文自动机)(PAM)

    第一个能看懂的论文:国家集训队2017论文集 这是我第一个自己理解的自动机(AC自动机不懂KMP硬背,SAM看不懂一堆引理定理硬背) 参考文献:2017国家集训队论文集 回文树及其应用 翁文涛 参考博 ...

  8. 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 ...

  9. 牛客多校第四场 I string 后缀自动机/回文自动机

    这个回文自动机的板有问题,它虽然能过这道题,但是在计算size的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...

随机推荐

  1. linux 中配置假域名来测试

    1.linux中配置假域名 找到hosts文件进行编辑 命令:vim /etc/hosts 配置: #centos(本机IP)192.168.1.179 www.imooc.com(假域名,自己设置) ...

  2. Windows下PHP服务nginx不能使用file_get_contents的原因

    注意:本文为转载,原文链接:Windows下PHP服务nginx不能使用file_get_contents/curl/fopen的原因! 一.问题说明 在Windows环境下搭建了一个本地开发服务环境 ...

  3. 【codeforces 803D】Magazine Ad

    [题目链接]:http://codeforces.com/contest/803/problem/D [题意] 给你一个字符串; 其中的空格和连字符表示可以折叠的部分 (就是说能在那个位置把字符串分成 ...

  4. BA--步进电机工作原理

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制元步进电机件.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,当步进驱动器接收到一个脉冲信号,它就驱动 ...

  5. [Angular] Component's dependency injection

    An Angular service registered on the NgModule is globally visible on the entire application. Moreove ...

  6. centos7.0 安装日志--图文具体解释-python开发环境配置

    centos7.0公布之后,就下载了everthing的DVD镜像.今天有时间,所以决定在vbox底下体验一番--- 上图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  7. hdu 5410 CRB and His Birthday 01背包和全然背包

    #include<stdio.h> #include<string.h> #include<vector> #include<queue> #inclu ...

  8. webRequest

    chrome.webRequest 描述: 使用 chrome.webRequest API 监控与分析流量,还可以实时地拦截.阻止或修改请求.  可用版本: 从 Chrome 17 开始支持.  权 ...

  9. 软件測试、ios中的測试概念以及步骤

    软件測试: 软件測试的目标是应该服务于软件项目的目标,能够通过建议反馈使用更加高效的方法和工具,提升软件开发效率以及软件开发质量.同一时候还能够通过过一些手段,更早.更快.很多其它地发现缺陷.从容减少 ...

  10. Java之旅--Web.xml解析

    Windows的IIS,是用UI界面进行网站的配置.Linux以下的差点儿全部系统,都是使用配置文件来进行配置,Java容器(JBoss/Tomcat/Jetty/WebSphere/WebLogic ...