ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

算法学习—————PAM回文自动机

2022-09-06 19:03:45  阅读:206  来源: 互联网

标签:ch pos PAM fail 自动机 preNode pam 回文


时隔一年,第一次学习新的算法

原理和AC自动机差不多

基本思想:

  1. 两棵树分别代表奇偶

  2. 在一个回文串两边同时填上相同字符可以得到另一个回文串,以此构建两棵树

树上维护信息:

  1. 节点表示的回文串为当前位置的最长回文串

  2. 节点上维护当前位置最长回文串的长度,fail指针(当前回文串的最长回文后缀)

如何维护:

  1. 若可以扩展,长度+2 判断条件: s[pos-len-1] == s[pos],否则跳fail

  2. 如何维护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;
}

标签:ch,pos,PAM,fail,自动机,preNode,pam,回文
来源: https://www.cnblogs.com/little-uu/p/16662959.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有