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的时候会出锅! 题意: 求一个字符串中本质不同的连续子串有几个,但是某串和它反转后的字符串算一个. 题解: 要注意的是,一般字符串题中的“ ...
随机推荐
- CSS - Span 下的width设置不可用?
解决:Span 下的width设置不可用? 内联元素-span有根据内容自动伸缩的能力,当需要对其宽度设定时,出现无效的情况. Demo:http://jsfiddle.net/JSDavi/ad62 ...
- 再见,OI(2019退役祭)
有些话应该藏在心里,有些事情只属于自己. (想了一下,自己的OI生涯.自己所经历的事情还是留在自己的心里吧,一是自己文笔不好,二是每个人的世界观不同对事情的看法不同) 不要轻易地去评价一个人,每个人背 ...
- NOIP2016 DAY2 T1 组合数问题
题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...
- Python hangman小游戏
hangman # words.py 使用pickle永久性存储数据 import pickle filename = 'words.pk' data = ['cat', 'dog', 'perro' ...
- js实现本地的图片压缩上传预览
js在设计时考虑到安全的原因是不允许读写本地文件的,随着html5的出现提供了fileReader AP从而可以I实现本地图片的读取预览功能, 另外在移动端有的限制图片大小的需求,主要是考虑图片过大会 ...
- JAVAEE网上商城项目总结
发送邮件实现(使用QQ邮箱发送到指定邮箱) 需要的jar 邮件发送类代码: package util; import java.util.Properties; import javax.mail.A ...
- 多播 & multicast
参考: http://blog.csdn.net/herbert5069/article/details/31358641
- pl/sql sql窗口允许输出和允许变量替换
pl/sql sql窗口允许输出和允许变量替换 允许输出:类似在命令窗口中输入的 setserveroutput on; 允许变量替换:如果点击了这个,类似于执行 set define off命令 在 ...
- Oracle 常见的33个等待事件
一. 等待事件的相关知识: 1.1 等待事件主要可以分为两类,即空闲(IDLE)等待事件和非空闲(NON-IDLE)等待事件. 1). 空闲等待事件指Oracle正等待某种工作,在诊断和优化数据库的时 ...
- angular4父组件向子组件传值,子组件向父组件传值的方法
父组件向子组件传值 @Input 文件目录 父组件: father.template.html <h1>父组件</h1> <cmt-child [data]='dat ...