算法学习—————PAM回文自动机
时隔一年,第一次学习新的算法
原理和AC自动机差不多
基本思想:
两棵树分别代表奇偶
在一个回文串两边同时填上相同字符可以得到另一个回文串,以此构建两棵树
树上维护信息:
节点表示的回文串为当前位置的最长回文串
节点上维护当前位置最长回文串的长度,fail指针(当前回文串的最长回文后缀)
如何维护:
若可以扩展,长度+2 判断条件: s[pos-len-1] == s[pos],否则跳fail
如何维护fail? 找到第一个可以扩展的位置,连出c边的点即是fail的指向
代码为洛谷模板题
当前节点的答案为他的fail的答案+1(可想而知,感觉而知)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define O(x) cout<<#x<<" "<<x<<endl;
#define B cout<<"Breakpoint"<<endl;
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
const int maxn = 5e5+10;
struct node{
int len,fail,ch[30];
}pam[maxn];
char s[maxn];
int n,preNode = 2,tot = 2;
int ans[maxn];
void insert(int pos){
if (pos > 1) s[pos] = (s[pos] - 97 + ans[preNode]) % 26 + 97;
int c = s[pos]-'a';
while (s[pos - pam[preNode].len - 1] != s[pos]) preNode = pam[preNode].fail;
if (pam[preNode].ch[c]) preNode = pam[preNode].ch[c];
else{
int nowNode = ++tot;
pam[preNode].ch[c] = nowNode;
pam[nowNode].len = pam[preNode].len + 2;
if (preNode == 1) pam[nowNode].fail = 2;
else{
for (preNode = pam[preNode].fail;s[pos - pam[preNode].len - 1] != s[pos];preNode = pam[preNode].fail);
pam[nowNode].fail = pam[preNode].ch[c];
}
preNode = nowNode;
}
ans[preNode] = ans[pam[preNode].fail] + 1;
cout<<ans[preNode]<<" ";
}
int main(){
scanf ("%s",s+1);
n = strlen(s+1);
pam[1].len = -1,pam[2].len = 0;
pam[2].fail = 1;
for (int i = 1;i <= n;i++) insert(i);
return 0;
}
算法学习—————PAM回文自动机的更多相关文章
- 省选算法学习-回文自动机 && 回文树
前置知识 首先你得会manacher,并理解manacher为什么是对的(不用理解为什么它是$O(n)$,这个大概记住就好了,不过理解了更方便做$PAM$的题) 什么是回文自动机? 回文自动机(Pal ...
- 回文树/回文自动机(PAM)学习笔记
回文树(也就是回文自动机)实际上是奇偶两棵树,每一个节点代表一个本质不同的回文子串(一棵树上的串长度全部是奇数,另一棵全部是偶数),原串中每一个本质不同的回文子串都在树上出现一次且仅一次. 一个节点的 ...
- 回文树(回文自动机PAM)小结
回文树学习博客:lwfcgz poursoul 边写边更新,大概会把回文树总结在一个博客里吧... 回文树的功能 假设我们有一个串S,S下标从0开始,则回文树能做到如下几点: 1.求串S前缀0~ ...
- 回文自动机pam
目的:类似回文Trie树+ac自动机,可以用来统计一些其他的回文串相关的量 复杂度:O(nlogn) https://blog.csdn.net/Lolierl/article/details/999 ...
- 洛谷P5496 回文自动机【PAM】模板
回文自动机模板 1.一个串的本质不同的回文串数量是\(O(n)\)级别的 2.回文自动机的状态数不超过串长,且状态数等于本质不同的回文串数量,除了奇偶两个根节点 3.如何统计所有回文串的数量,类似后缀 ...
- URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
Palindromes and Super Abilities 2 题目链接: http://acm.hust.edu.cn/vjudge/contest/126823#problem/E Descr ...
- 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做
题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...
- 【XSY2715】回文串 树链剖分 回文自动机
题目描述 有一个字符串\(s\),长度为\(n\).有\(m\)个操作: \(addl ~c\):在\(s\)左边加上一个字符\(c\) \(addr~c\):在\(s\)右边加上一个字符 \(tra ...
- 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)
模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...
- 【CF932G】Palindrome Partition 回文自动机
[CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_ ...
随机推荐
- P31_全局配置 - window - 设置上拉触底的距离
window 设置上拉触底的距离 概念:上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为. 设置步骤: app.json -> window -> 为 o ...
- 郁金香 注入DLL代码 与MFC窗口DLL文件 开源
10/10号更新 DLL注入器注入DLL卡死 问题 新增打开控制台 将阳光输出到控制台中 注入DLL代码 1 #include <stdio.h> 2 #include<Window ...
- ctf 菜鸟杯
web签到 首先最里面的是ctfshow-QQ群:,而他需要进行cookie传参,因此我们需要在cookie传入CTFshow-QQ群=a,然后就要以POST方式传入a的值,我们传入a=b,而b是以G ...
- 国内“谁”能实现chatgpt,短期穷出的类ChatGPT简评(算法侧角度为主),以及对MOSS、ChatYuan给出简评,一文带你深入了解宏观技术路线。
1.ChatGPT简介[核心技术.技术局限] ChatGPT(全名:Chat Generative Pre-trained Transformer),美国OpenAI 研发的聊天机器人程序 ,于202 ...
- Gear_Of_War#1
Gear_Of_War#1 目录 Gear_Of_War#1 1 信息收集 1.1 端口扫描 1.2 后台目录扫描 1.3 SMB服务安全分析 2 GetShell 2.1 ssh登录marcus用户 ...
- 代码随想录算法训练营day14 | leetcode 层序遍历 226.翻转二叉树 101.对称二叉树 2
层序遍历 /** * 二叉树的层序遍历 */ class QueueTraverse { /** * 存放一层一层的数据 */ public List<List<Integer>&g ...
- 代码随想录算法训练营day10 | leetcode 232.用栈实现队列 225. 用队列实现栈
基础知识 使用ArrayDeque 实现栈和队列 stack push pop peek isEmpty() size() queue offer poll peek isEmpty() size() ...
- 《爆肝整理》保姆级系列教程-玩转Charles抓包神器教程(8)-Charles如何进行断点调试
1.简介 Charles和Fiddler一样也有个强大的功能,可以修改发送到服务器的数据包,但是修改前需要拦截,即设置断点.设置断点后,开始拦截接下来所有网页,直到取消断点.这个功能可以在数据包发送之 ...
- jquery获得标签的值或元素的内容
例如: .html() 获取a标签中的i元素 console.error($("a[name=" + index + "]").html()); 设置a标签里的 ...
- 按照参数名ASCII码表升序顺序排序,生成签名用
签名生成方法如下: 对所有请求参数(不包括 signature 参数),按照参数名ASCII码表升序顺序排序.如:foo=1, bar=2, foo_bar=3, baz=4 排序后的顺序是 bar= ...