回文树 - 模板

回文树(模板)+ 例题 引用: Palindromic Tree——回文树【处理一类回文串问题的强力工具】 回文树练习题集 首先,回文树有何功能? 假设我们有一个串S,S下标从0开始,则回文树能做到如下几点: 1.求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同) 2.求串S内每一个本质不同回文串出现的次数 3.求串S内回文串的个数(其实就是1和2结合起来)... 阅读详情
学习链接:点击进入
介绍

回文树通常用来解决一些回文串问题
空间复杂度 O( N * 字符集大小 )
时间复杂度 O( N * log( 字符集大小 ))

功能
  1. 求串 S 前缀 0 ~ i 内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同)

  2. 求串 S 内每一个本质不同回文串出现的次数

  3. 求串 S 内回文串的个数

  4. 求以下标 i 结尾的回文串的个数

存储
  1. len [ i ] 表示编号为 i 的节点表示的回文串的长度(一个节点表示一个回文串)

  2. next [ i ] [ c ] 表示编号为 i 的节点表示的回文串在两边添加字符 c 以后变成的回文串的编号(和字典树类似)。

  3. fail [ i ] 表示节点 i 失配以后跳转不等于自身的节点 i 表示的回文串的最长后缀回文串(和AC自动机类似)。

  4. cnt [ i ] 表示节点 i 表示的本质不同的串的个数(建树时求出的不是完全的,最后count()函数跑一遍以后才是正确的)

  5. num [ i ] 表示以节点 i 表示的最长回文串的最右端点为回文串结尾的回文串个数。

  6. last 指向新添加一个字母后所形成的最长回文串表示的节点。

  7. S [ i ] 表示第 i 次添加的字符(一开始设 S [ 0 ] = -1(可以是任意一个在串 S 中不会出现的字符))。

  8. p 表示添加的节点个数。

  9. n 表示添加的字符个数。

初始化

回文树初始有两个根节点,0 表示偶数长度串的根,1 表示奇数长度串的根。
len [ 0 ] = 0,len [ 1 ] = -1,last = 0,S [ 0 ] = -1,n = 0,p = 2( 添加了节点 0 、1 )。

代码1( 邻接矩阵版 )
const int maxn=1e5+10;
const int N=26;

/******邻接矩阵******/
struct Palindromic_Tree 
{
	int next[maxn][N];//next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成
	int fail[maxn];//fail指针,失配后跳转到fail指针指向的节点
	int cnt[maxn];//表示节点i表示的回文串出现的次数
	int num[maxn];//表示以节点i表示的回文串的最右端点为回文串结尾的回文串个数。
	int len[maxn];//len[i]表示节点i表示的回文串的长度
	int S[maxn];//存放添加的字符
	int last;//指向上一个字符所在的节点,方便下一次add
	int n;//字符数组指针
	int p;//节点指针
	int newnode(int l)//新建节点
	{
		for(int i=0;i<N;++i) 
			next[p][i]=0;
		cnt[p]=0;
		num[p]=0;
		len[p]=l;
		return p++;
	}
	void init()//初始化
	{
		p=0;
		newnode(0);//0表示偶数长度串的根,len[0]=0 
		newnode(-1);//1表示奇数长度串的根,len[1]=-1 
		last=0;
		n=0;
		S[n]=-1;//开头放一个字符集中没有的字符,减少特判
		fail[0]=1;
	}
	int get_fail(int x)//和KMP一样,失配后找一个尽量最长的
	{
		while(S[n-len[x]-1]!=S[n]) 
			x=fail[x];
		return x;
	}
	void add(int c) 
	{
		c-='a';
		S[++n]=c;
		int cur=get_fail(last);//通过上一个回文串找这个回文串的匹配位置
		if(!next[cur][c])//如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串
		{
			int now=newnode(len[cur]+2);//新建节点
			fail[now]=next[get_fail(fail[cur])][c];//和AC自动机一样建立fail指针,以便失配后跳转
			next[cur][c]=now;
			num[now]=num[fail[now]]+1;
		}
		last=next[cur][c];
		cnt[last]++;
	}
	void count()
	{
		for(int i=p-1;i>=0;--i) 
			cnt[fail[i]]+=cnt[i] ;
		//父亲累加儿子的cnt,因为如果fail[v]=u,则u一定是v的子回文串!
	}
}patree;
代码2( 邻接表版 )
const int maxn=1e5+10;

/*邻接表*/
struct Palindromic_Tree 
{
    vector<pair<int,int>>next[maxn];//next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成
	int fail[maxn];//fail指针,失配后跳转到fail指针指向的节点
	int cnt[maxn];//表示节点i表示的回文串出现的次数
	int num[maxn];//表示以节点i表示的回文串的最右端点为回文串结尾的回文串个数。
	int len[maxn];//len[i]表示节点i表示的回文串的长度
	int S[maxn];//存放添加的字符
	int last;//指向上一个字符所在的节点,方便下一次add
	int n;//字符数组指针
	int p;//节点指针
    int newnode(int w)
    {
        next[p].clear();
        cnt[p]=num[p]=0;
        len[p]=w;
        return p++;
    }
    void init()
    {
        p=0;
        newnode(0);
        newnode(-1);
        last=0;
        n=0;
        S[n]=-1;
        fail[0]=1;
    }
    int get_fail(int x)
    {
        while(S[n-len[x]-1]!=S[n]) 
			x=fail[x];
        return x;
    }
    void add(int c)
    {
        c-='a';
        S[++n]=c;
        int cur=get_fail(last);
        int flag=0;
        for(int i=0;i<next[cur].size();++i)
        {
        	if(next[cur][i].first==c)
            {
                last=next[cur][i].second;
                cnt[last]++;
                return ;
            }
		}
        int now=newnode(len[cur]+2);
        int fi=get_fail(fail[cur]);
        flag=0;
        for(int i=0;i<next[fi].size();i++)
        {
        	if(next[fi][i].first==c)
            {
                flag=next[fi][i].second;
                break;
            }
		}
        fail[now]=flag;
        next[cur].push_back(make_pair(c,now));
        num[now]=num[flag]+1;
        last=now;
        cnt[now]++;
    }
    void count()
    {
        for(int i=p-1;i>1;--i)
            cnt[fail[i]] += cnt[i];
    }
}patree;
Zephyr内核——内存管理——内存堆 Zephyr提供了一组允许线程动态分配内存。 阅读详情

相关推荐

PLC模拟量输入电路设计:±10V与±20mA信号调理全解析

在工业自动化和数据采集系统中,模拟量输入是连接物理世界与数字控制的核心桥梁。无论是变送器输出的4-20mA电流环,还是伺服驱动与信号发生器提供的±10V电压信号,PLC和采集模块都需要在复杂现场环境下稳定、精准地完成信号采集。理解信号体制的原理——电流环抗长线干扰、电压环响应快——是设计模拟输入前端的基础。通过精密电阻网络实现分压与采样,利用运放完成双极性到单极性的电平搬移,配合TVS与滤波电路保障可靠性,并经过ADC量化与校准流程,最终构建出兼顾精度、成本和工业级鲁棒性的完整信号链路。本文面向硬件工程师与

weixin_29163797的博客 297

回文串

题目链接 回文树模板 cnt数组表示当前串在所有会问字串中出现的次数 len数组表示当前串的长度 num数组表示当前串的字串中本质不同的回文子串个数包括自己 p表示所有的本质不同的回文子串.(p - 2) #include<iostream> #include<cstdio> #include<cstring> #define max(a,b) ((a)>...

qq_41650771的博客 202

RDD2022 数据格式转换与清洗

Rdd2022数据集,是关于道路损伤的数据集,与rdd2020相比增加了两万多张图片但是由于格式不能被yolo直接使用且其中有大量的图片没有符合要求的标注,特写此文章记录数据清洗与格式化的过程。

蓝胖子的博客 9946

URAL - 1960 Palindromes and Super Abilities

题意:          给出一个串,问对于串的每个前缀各包含多少种回文串 思路:          按http://blog.youkuaiyun.com/u013368721/article/details/42100363 所讲 回文树 的思路所写。 代码: #include using namespace std; const int MAXN = 100005 ; const int N

DT2131 536

深入解析 TDA4VM/VH R5F 核中断机制:VIC 与非 VIC 模式下的实战对比与优化

本文深入解析了TI TDA4VM/VH平台中ARMv7-R架构R5F核的两种中断处理机制:VIC模式与非VIC模式。通过对比硬件自动跳转与软件向量表分发的核心流程、实战代码示例及性能差异,为开发者提供了基于实时性、灵活性与调试需求的选择指南和优化建议,帮助构建更稳定的嵌入式系统。

weixin_29159441的博客 98

FRM模型五:Brinson业绩归因

利用Brinson对基金组合业绩进行归因分析。

stonesssssss的博客 3003

回文树小结

回文树是一个用来解决回文串相关问题的数据结构。回文树由若干个节点组成,每个节点代表一个回文串。相比于manacher,回文树要显得强大的多,同样是接近o(n)的复杂度,回文树只需要多一点的空间,就可以实现许多用manacher实现起来非常复杂的功能,并且能解决很多关于回文串的问题。节点之间通过有向边连接起来,回文树中有两种类型的边:第一种类型的边上同时有字符做标记,比如:u和v通过带字符x通过带字...

wang_128的博客 490

STM32F103C8T6通过ESP8266连接阿里云物联网平台(附代码)

STM32F103C8T6连接阿里云物联网平台(1)—阿里云lot Studio控制 Web开发 分享一下自己使用stm32f103c8t6通过ESP_01模块连接阿里云物联网平台,实现温湿度上传和控制命令下达的过程,能力有限,用的是最简单的方法,如有错误,多多担待。 一、硬件选型 1、 stm32f103c8t6 2、ESP_01 wifi模块 3、其他 二、硬件连接 WSP_01 STM32F103C8T6 RXD PA2 TXD PA3 RES PA4 VCC 3.3

weixin_A13253323604 3万+

Palindromic Tree——回文树【处理一类回文串问题的强力工具】

今天我们来学习一个神奇的数据结构:Palindromic Tree。中译过来就是——回文树。 那么这个回文树有何功能? 假设我们有一个串S,S下标从0开始,则回文树能做到如下几点: 1.求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同) 2.求串S内每一个本质不同回文串出现的次数 3.求串S内回文串的个数(其实就是1和2结合起来)

poursoul 2万+

从Oracle迁移数据到Hadoop

目标:把Oracle 下的数据文件迁移到 Hadoop , 数据表都是上亿条,每个数据表的空间都超过100G。 关键是建立数据文件是UTF8格式,这样数据中的汉字在Hadoop 里显示才正常。 平台:CentOS 6.10 工具:Python 2.7 cx_Oracle 库 Oracle10.2.0.4.0 Hadoop 2.7.2-transwarp-5.2.1 1. 查看表...

预则立 4233

国科大学习资料--机器人智能控制_袁如意老师PPT后习题答案(学长精心整理)

人工神经元激活函数的作用是什么? 答:激活函数是用来加入非线性因素的,提高神经网络对模型的表达能力,解决线性模型所不能解决的问题。 人工神经网络的学习规则有哪些?各有何特征? 答:大类可以分为无监督学习算法、有监督学习算法和强化学习。其中无监督学习算法指只有输入信息,没有期望的输出信息,如Hebb学习规则,神经元连接强度的变化与两个相互连接的神经元的激活水平成正比。竞争学习法则:网络各输出单元相互竞争,最后达到只有一个最强者激活。有监督学习算法指同时提供输入信息和对应的期望输出信息,如误差学习(Delta学

无名何许人的博客 1486

回文树模板

原文链接: http://blog.youkuaiyun.com/u013368721/article/details/42100363 回文树可以: 1.求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同) 2.求串S内每一个本质不同回文串出现的次数 3.求串S内回文串的个数(其实就是1和2结合起来) 4.求以下标i结尾的回文串的个数那么我们该如何构

MrBlank的ACM记事本 492

X电容与Y电容,看这一篇就够了

本文详细介绍了X电容与Y电容的定义、作用、位置、分类,以及它们在实际应用中的容值选取和计算方法。通过汽车电子应用和X电容放电电路的实例,帮助读者深入理解这两种安规电容的重要性。文章还探讨了电容放电电阻的计算,确保符合安全规范。

让你爱上电路设计 7015

回文树模板整理

有的算法只会模板题真不行,有的算法没有理解深刻照样不会做题,今天又看了一遍回文树,加深了一下理解,顺便整理一下模板 超好理解 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 1...

青春苦瓜 269

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

回文树学习笔记(模板)

好好理解了回文树。 理解后的感觉:为啥子之前会觉得很复杂?Orz 根据自己理解改了个自己能看懂的模板 #include<bits/stdc++.h> using namespace std; const int maxn=1e5+50; int last,tot,n; int next[maxn][27],len[maxn],fa...

a657285080的博客 153

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

[回文树 模板]

解决回文的有力武器 BZOJ 3676 题目大意:考虑一个只包含小写拉丁字母的符串s。我们定义s的一个子串 t的“出现值”为t在s中的出现次数乘以t的长度。 请你求出s的所有 回文子串中的最大出现值。 代码 #include &amp;lt;bits/stdc++.h&amp;gt; using namespace std; typedef long long ll; const int N = 30001...

lzs_lazy 248

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【BZOJ3676】【UOJ103】【APIO2014】【回文树模板题】回文串

Description http://uoj.ac/problem/103 Solution 回文树模板题。 感觉和SAM一个样啊 具体看2017年wwt的论文吧233 Code /************************************************ * Au: Hany01 * Date: Jun 21st, 2018 * Prob...

დ♂Hany01's Blog Space♂ღ 300

HDU3948 & 回文树模板

Description:   求本质不同回文子串的个数 Solution:   回文树模板,学一学贴一贴啊... Code:    /*================================= # Created time: 2016-04-20 20:55 # Filename: hdu3948.cpp # Description: =============...

weixin_30897233的博客 137

回文树(模板)

一、复杂度     构造回文树需要的空间复杂度为O(N*字符集大小),时间复杂度为O(N*log(字符集大小)) 二、应用 1、求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同) 2、求串S内每一个本质不同回文串出现的次数 3、求串S内回文串的个数(其实就是1和2结合起来) 4、求以下标i结尾的回文串的个数 三、...

weixin_38168173的博客 117

回文树模板 hdu3948

题目链接:https://vjudge.net/problem/HDU-3948 题意:输出每个串有多少个子串是回文串 转自:http://www.pianshen.com/article/86272661/ 因为一开始就有了两个节点,所以输出是应该-2. #include <bits/stdc++.h> using namespace std; const int MAXN = 10...

A 234

回文树题目整理【模板】

题目中模板部分来源于网络大神,一般不改动只有第一个给出,其他只写关键部分。 A UVALive 7041 【裸】 题意:求两个串的公共回文串的个数。0 < A,B <200000 #include <iostream> #include<bits/stdc++.h> using namespace std; const int MAXN = 21000...

Mercury_Lc的博客 270

回文树 模板

类似AC自动机,树里面每个节点代表主串的一个回文子串,且每个回文子串都不同 主要功能: 1.求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同) 2.求串S内每一个本质不同回文串出现的次数 3.求串S内回文串的个数 4.求以下标i结尾的回文串的个数 参考链接: https://blog.youkuaiyun.com/yxuanwkeith/article...

Sun Sun day的博客 122
上一篇: CodeForces - 1538G Gift Set - ( 二分 )
下一篇: 黑暗爆炸 - 2565 - 最长双回文串 - ( 回文树 )
Cosmic_Tree
博客等级 码龄7年 134粉丝 337原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值