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

开头结尾都维护一个$last$指针,如果插入新字符后,整个串是一个回文串,就把另一个$last$赋值成当前的$last$

为什么这样做就是正确的呢?

首先,对于这道题而言,一个回文串开头/结尾是等价的

不合并$last$的情况下,在当前方向添加字符不会被另一个方向所影响,就相当于只在末尾加字符

如果合并了$last$,说明现在另一个方向的开头字符,能和新添加的字符共同产生贡献,所以必须把另一个$last$赋值成当前的$last$,来完成都是在末尾新添加字符的“假象”

本质不同的回文串数量就是节点个数,回文串总数量就是所有节点在$pre$树中的深度总和*作为回文末尾的次数

每次$insert$时都更新即可,注意开$longlong$

  1. #include <cmath>
  2. #include <vector>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. #define N1 200100
  7. #define S1 (N1<<1)
  8. #define ll long long
  9. #define uint unsigned int
  10. #define rint register int
  11. #define dd double
  12. #define il inline
  13. #define inf 0x3f3f3f3f
  14. #define idx(X) (X-'a')
  15. using namespace std;
  16.  
  17. int gint()
  18. {
  19. int ret=,fh=;char c=getchar();
  20. while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
  21. while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
  22. return ret*fh;
  23. }
  24. int n,L,R;
  25. namespace PAM{
  26. int trs[N1][],pre[N1],dep[N1],num[N1];
  27. int lla,rla,tot;ll sum;
  28. void init(){tot=lla=rla=,dep[]=-,pre[]=pre[]=;}
  29. int lchk(char *str,int i,int p){return str[i+dep[p]+]!=str[i]?:;}
  30. int rchk(char *str,int i,int p){return str[i-dep[p]-]!=str[i]?:;}
  31. void Lins(char *str,int i)
  32. {
  33. int p=lla,np,fp,c=idx(str[i]);
  34. while(lchk(str,i,p)) p=pre[p];
  35. if(!trs[p][c])
  36. {
  37. np=++tot;
  38. dep[np]=dep[p]+;
  39. fp=pre[p];
  40. while(lchk(str,i,fp)) fp=pre[fp];
  41. pre[np]=trs[fp][c];
  42. trs[p][c]=np;
  43. num[np]=num[pre[np]]+;
  44. }
  45. lla=trs[p][c];
  46. if(dep[trs[p][c]]==R-L+) rla=lla;
  47. sum+=num[lla];
  48. }
  49. void Rins(char *str,int i)
  50. {
  51. int p=rla,np,fp,c=idx(str[i]);
  52. while(rchk(str,i,p)) p=pre[p];
  53. if(!trs[p][c])
  54. {
  55. np=++tot;
  56. dep[np]=dep[p]+;
  57. fp=pre[p];
  58. while(rchk(str,i,fp)) fp=pre[fp];
  59. pre[np]=trs[fp][c];
  60. trs[p][c]=np;
  61. num[np]=num[pre[np]]+;
  62. }
  63. rla=trs[p][c];
  64. if(dep[trs[p][c]]==R-L+) lla=rla;
  65. sum+=num[rla];
  66. }
  67. void clr()
  68. {
  69. tot++;
  70. memset(trs,,tot**);
  71. memset(pre,,tot*);
  72. memset(dep,,tot*);
  73. memset(num,,tot*);
  74. tot=lla=rla=;sum=;
  75. }
  76. };
  77. char str[N1];
  78.  
  79. int main()
  80. {
  81. //freopen("t2.in","r",stdin);
  82. //freopen("a.out","w",stdout);
  83. while(scanf("%d",&n)!=EOF)
  84. {
  85. int fl;L=,R=;
  86. char tmp[];
  87. PAM::clr(),PAM::init();
  88. memset(str,,sizeof(str));
  89. while(n--)
  90. {
  91. scanf("%d",&fl);
  92. if(fl==){
  93. scanf("%s",tmp);
  94. str[--L]=tmp[];
  95. PAM::Lins(str,L);
  96. }else if(fl==){
  97. scanf("%s",tmp);
  98. str[++R]=tmp[];
  99. PAM::Rins(str,R);
  100. }else if(fl==){
  101. printf("%d\n",PAM::tot-);
  102. }else if(fl==){
  103. printf("%lld\n",PAM::sum);
  104. }
  105. }
  106. }
  107. return ;
  108. }

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. CSS - Span 下的width设置不可用?

    解决:Span 下的width设置不可用? 内联元素-span有根据内容自动伸缩的能力,当需要对其宽度设定时,出现无效的情况. Demo:http://jsfiddle.net/JSDavi/ad62 ...

  2. 再见,OI(2019退役祭)

    有些话应该藏在心里,有些事情只属于自己. (想了一下,自己的OI生涯.自己所经历的事情还是留在自己的心里吧,一是自己文笔不好,二是每个人的世界观不同对事情的看法不同) 不要轻易地去评价一个人,每个人背 ...

  3. NOIP2016 DAY2 T1 组合数问题

    题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...

  4. Python hangman小游戏

    hangman # words.py 使用pickle永久性存储数据 import pickle filename = 'words.pk' data = ['cat', 'dog', 'perro' ...

  5. js实现本地的图片压缩上传预览

    js在设计时考虑到安全的原因是不允许读写本地文件的,随着html5的出现提供了fileReader AP从而可以I实现本地图片的读取预览功能, 另外在移动端有的限制图片大小的需求,主要是考虑图片过大会 ...

  6. JAVAEE网上商城项目总结

    发送邮件实现(使用QQ邮箱发送到指定邮箱) 需要的jar 邮件发送类代码: package util; import java.util.Properties; import javax.mail.A ...

  7. 多播 & multicast

    参考: http://blog.csdn.net/herbert5069/article/details/31358641

  8. pl/sql sql窗口允许输出和允许变量替换

    pl/sql sql窗口允许输出和允许变量替换 允许输出:类似在命令窗口中输入的 setserveroutput on; 允许变量替换:如果点击了这个,类似于执行 set define off命令 在 ...

  9. Oracle 常见的33个等待事件

    一. 等待事件的相关知识: 1.1 等待事件主要可以分为两类,即空闲(IDLE)等待事件和非空闲(NON-IDLE)等待事件. 1). 空闲等待事件指Oracle正等待某种工作,在诊断和优化数据库的时 ...

  10. angular4父组件向子组件传值,子组件向父组件传值的方法

    父组件向子组件传值   @Input 文件目录 父组件: father.template.html <h1>父组件</h1> <cmt-child [data]='dat ...