• 【算法学习】回文树


    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+50;
    struct PT{
    	//回文树中每个节点表示一个回文串,所以有偶数长度的树和奇数长度的树两棵
    	//next指针 next[u][i]表示u节点左右添加字符i之后得到的回文串节点
    	int next[N][26];
    	//fail指针 失配后跳转到最长后缀回文串对应的节点
    	int fail[N];
    	//节点对应回文串在原串中出现次数
    	int cnt[N];
    	//num[i]表示以节点i所表示的回文串右端点结尾的回文串个数(包括自身),即fail指针的深度
    	int num[N];
    	//节点对应回文串的长度
    	int len[N];
    	//存放添加的字符
    	int S[N];
    	//上一个字符所在节点
    	int last;
    	//字符数,不等于节点数
    	int n;
    	//回文树总结点数,包括奇偶两个空节点,节点编号为0到p-1
    	int p;
    	//初始化
    	void init(){
    		p=0;
    		//奇偶空节点
    		newnode(-1);
    		newnode(0);
    		last=0;
    		n=0;
    		S[n]=-1;
    		//偶数根的fail指针是奇数根,奇数根的fail指针是本身
    		fail[0]=1;
    	}
    	//创建长度为l的新节点
    	int newnode(int l){
    		for(int i=0;i<26;i++){
    			next[p][i]=0;
    		}
    		cnt[p]=0;
    		num[p]=0;
    		len[p]=l;
    		return p++;
    	}
    	//找到新插入字符c的回文匹配位置
    	int getFail(int x){
    		//在节点x对应串的后面加上一个字符,就判断x前面字符是否相同
    		//若相同直接构成新的回文串,不同就跳到fail,即最长回文后缀
    		//S[n-len[x]-1]就是新加的字符(S[n])关于x串的对称字符
    		while(S[n-len[x]-1]!=S[n]){
    			x=fail[x];
    		}
    		return x;
    	}
    	//插入字符c
    	void add(int c){
    		c-='a';
    		S[++n]=c;
    		//通过上一个回文串位置找到当前回文串匹配位置,也就是当前回文串节点的父节点
    		int cur=getFail(last);
    		if(!next[cur][c]){
    			//出现了一个新的本质不同的回文串
    			int now=newnode(len[cur]+2);
    			//类似于AC自动机,往上跳直到找到满足条件的串节点
    			fail[now]=next[getFail(fail[cur])][c];
    			//fail指针深度加1
    			num[now]=num[fail[now]]+1;
    		}
    		//最新回文串节点
    		last=next[cur][c];
    		cnt[last]++;
    	}
    	//统计每个节点回文串出现次数
    	void count(){
    		//从子节点逆推
    		for(int i=p-1;i>=0;i--){
    			//i节点出现,说明其最长回文后缀fail[i]也出现
    			cnt[fail[i]]+=cnt[i];
    		}
    	}
    }ac;
    int main(void){
    	return 0;
    }
    
  • 相关阅读:
    linux下进程的实际用户ID(有效组)和有效用户ID(有效组ID)
    ubuntu下软件中心闪退问题解决
    LINUX(UNIX)文件I/O学习
    ubunut下桌面文件路径修改
    ubuntu下设置jdk/jre环境
    Fire net
    JavaScript 自己写一个 replaceAll() 函数
    Canvas 绘制一个像素风电子时钟
    Python3 笔记01:求两数之和
    尝试笔记 01 之 CSS 边角上的标签
  • 原文地址:https://www.cnblogs.com/zxcoder/p/11242979.html
Copyright © 2020-2023  润新知