zoukankan      html  css  js  c++  java
  • 回文自动机 PAM

    也叫回文树

    PAM可以处理出一个串的所有不同的回文串与它们的出现次数

    回文树比较简单,每次执行 insert 操作后的状态节点都是以这个字母为结尾的后缀的最长回文串,fail指针指的是长度小于它的下一个后缀回文串。

    一个串的所有不同的回文子串就是回文树上的所有节点 - 2, 除了两个根节点

    P5496 【模板】回文自动机(PAM) - 洛谷

    /*
     * @Author: zhl
     * @Date: 2020-11-24 11:57:26
     */
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 2e6 + 10;
    
    struct Node {
    	int ch[26], fail;
    	int len, sum;
    }tr[N];
    
    char s[N];
    int last, tot = 2;
    
    int newnode(int len) {
    	tr[tot].len = len;
    	//tr[tot].fail = 0;
    	//for(int i = 0;i < 26;i++)tr[tot].ch[i] = 0;
    	return tot++;
    }
    int getFail(int x, int pos) {
    	while (s[pos - tr[x].len - 1] != s[pos]) x = tr[x].fail;
    	return x;
    }
    
    void init() {
    	tr[0].len = 0, tr[1].len = -1;
    	tr[0].fail = 1; tr[1].fail = 0;
    	//for(int i = 0;i < 26;i++)tr[0].ch[i] = tr[1].ch[i] = 0;
    	last = 0;
    }
    
    void insert(int pos) {
    	int cur = getFail(last, pos);
    	int c = s[pos] - 'a';
    	if (tr[cur].ch[c] == 0) {
    		int now = newnode(tr[cur].len + 2);
    		tr[now].fail = tr[getFail(tr[cur].fail, pos)].ch[c]; //fail指向后缀中的最长回文串
    		tr[now].sum = tr[tr[now].fail].sum + 1;
    		tr[cur].ch[c] = now;
    	}
    	last = tr[cur].ch[c];
    }
    
    int main() {
    	scanf("%s", s + 1);
    	int k = 0; int n = strlen(s + 1);
    	init();
    	for (int i = 1; i <= n; i++) {
    		s[i] = (s[i] - 97 + k) % 26 + 97;
    		insert(i);
    		printf("%d ", tr[last].sum);
    		k = tr[last].sum;
    	}
    }
    
  • 相关阅读:
    intel cpu 架构
    nginx-nagios-pnp4nagios-nrpe安装配置过程
    iostat 命令detail
    nagios环境
    编译安装PHP 5.3.13
    nagios支持PNP图形显示
    nagios配置安装
    在xp下禁用media sense
    linux awk常用命令【转载】
    sed命令解析[转载]
  • 原文地址:https://www.cnblogs.com/sduwh/p/14036106.html
Copyright © 2011-2022 走看看