回文树练习

回文树是两棵树, 分别存储奇回文和偶回文.

显然一个字符串本质不同的回文个数是不超过$n$, 回文树的每个节点都表示一个本质不同的回文串. 节点$x$向节点$y$连一条有向边$c$表示$y$的回文串可以由$x$的回文串两端添加字符$c$得到. 每个节点设fail指针, 指向该节点表示的回文串的第二长的回文后缀所在节点.

奇回文根为$1$号节点, 偶回文根为$0$号节点, 要初始化$s[0]$为一个特殊字符.

$fail[0]$要指向奇回文的根, $fail[1]$在$getfail$时不会一定被访问到, 设成0即可.

 

练习1 hdu3068 最长回文

给出字符串, 求最长回文长度.

#include <iostream>
#include <string.h>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int n, tot, last, fail[N], len[N], ch[N][26];
char s[N];

int getfail(int x, int n) {
	while (s[n-len[x]-1]!=s[n]) x=fail[x];
	return x;
}

int main() {
	while (~scanf("%s", s+1)) {
		s[0]='#',fail[0]=1,last=0;
		len[0]=0,len[1]=-1,tot=1;
		n = strlen(s+1);
		REP(i,1,n) {
			s[i] -= 'a';
			int p = getfail(last,i);
			if (!ch[p][s[i]]) {
				len[++tot] = len[p]+2;
				fail[tot]=ch[getfail(fail[p],i)][s[i]];
				ch[p][s[i]]=tot;
			}
			last=ch[p][s[i]];
		}
		int ans = 0;
		REP(i,0,tot) {
			memset(ch[i],0,sizeof ch[0]);
			ans = max(ans, len[i]);
			fail[i]=len[i]=0;
		}
		printf("%d\n", ans);
	}
}

 

 

 

练习2 hdu 4513 吉哥系列故事——完美队形II

求最长的左侧非降, 右侧非增的回文串.

#include <iostream>
#include <map>
#include <string.h>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int n, tot, last, a[N];
int fail[N], len[N];
map<int,int> ch[N];
int val[N];

int getfail(int x, int n) {
	while (a[n-len[x]-1]!=a[n]) x=fail[x];
	return x;
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		REP(i,1,n) scanf("%d", a+i);
		a[0]=-1,fail[0]=1,last=0;
		len[0]=0,len[1]=-1,tot=1;
		REP(i,1,n) {
			int p = getfail(last,i);
			if (!ch[p].count(a[i])) {
				len[++tot] = len[p]+2;
				fail[tot]=ch[getfail(fail[p],i)][a[i]];
				ch[p][a[i]]=tot;
				if (len[tot]<=2) val[tot]=len[tot];
				else if (a[i]<=a[i-1]) val[tot]=val[p]+2;
				else val[tot]=-1e9;
			}
			last=ch[p][a[i]];
		}
		int ans = 0;
		REP(i,0,tot) {
			ch[i].clear();
			ans = max(ans, val[i]);
			val[i]=fail[i]=len[i]=0;
		}
		printf("%d\n", ans);
	}
}

 

 

练习3 hdu 3948 The Number of Palindromes

求本质不同的回文串个数.

#include <iostream>
#include <string.h>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int n, tot, last, fail[N], len[N], ch[N][26];
char s[N];

int getfail(int x, int n) {
	while (s[n-len[x]-1]!=s[n]) x=fail[x];
	return x;
}

int main() {
	int t;
	scanf("%d", &t);
	REP(cas,1,t) {
		scanf("%s", s+1);
		s[0]='#',fail[0]=1,last=0;
		len[0]=0,len[1]=-1,tot=1;
		n = strlen(s+1);
		REP(i,1,n) {
			s[i] -= 'a';
			int p = getfail(last,i);
			if (!ch[p][s[i]]) {
				len[++tot] = len[p]+2;
				fail[tot]=ch[getfail(fail[p],i)][s[i]];
				ch[p][s[i]]=tot;
			}
			last=ch[p][s[i]];
		}
		REP(i,0,tot) {
			memset(ch[i],0,sizeof ch[0]);
			fail[i]=len[i]=0;
		}
		printf("Case #%d: %d\n", cas, tot-1);
	}
}

 

 

练习4 ZOJ 3661 Palindromic Substring

给定字符串, 每个字符有一个价值范围[0,25], 每个回文子串的价值为前一半所表示的26进制数, 求第$k$大价值.

回文树预处理出所有本质不同的回文的价值, 然后排序即可, 要注意回文子串的总数爆int

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int n, m, tot, last, fac[N];
int fail[N], len[N], ch[N][26], val[25][N];
int rk[25][26], cnt[N];
ll k[25];
char s[N];
struct _ {int v,cnt;} a[N];

int getfail(int x, int n) {
	while (s[n-len[x]-1]!=s[n]) x=fail[x];
	return x;
}

int main() {
	fac[0]=1;
	REP(i,1,N-1) fac[i]=fac[i-1]*26ll%777777777;
	int t;
	scanf("%d", &t);
	REP(cas,1,t) {
		scanf("%d%d%s", &n, &m, s+1);
		s[0]='#',fail[0]=1,last=0;
		len[0]=0,len[1]=-1,tot=1;
		n = strlen(s+1);
		REP(i,1,m) {
			scanf("%lld", k+i);
			REP(j,0,25) scanf("%d", rk[i]+j);
		}
		REP(i,1,n) {
			s[i] -= 'a';
			int p = getfail(last,i);
			if (!ch[p][s[i]]) {
				len[++tot] = len[p]+2;
				fail[tot]=ch[getfail(fail[p],i)][s[i]];
				ch[p][s[i]]=tot;
				REP(j,1,m) { 
					val[j][tot]=(val[j][p]+(ll)rk[j][s[i]]*fac[(len[tot]+1)/2-1])%777777777;
				}
			}
			++cnt[last=ch[p][s[i]]];
		}
		PER(i,1,tot) cnt[fail[i]]+=cnt[i];
		REP(i,1,m) {
			REP(j,1,tot-1) a[j].v=val[i][j+1],a[j].cnt=cnt[j+1];
			sort(a+1,a+tot,[](_ a,_ b){return a.v<b.v;});
			REP(j,1,tot-1) {
				if (k[i]<=a[j].cnt) {
					printf("%d\n", a[j].v);
					break;
				}
				k[i] -= a[j].cnt;
			}
		}
		REP(i,0,tot) {
			memset(ch[i],0,sizeof ch[0]);
			REP(j,1,m) val[j][i]=0;
			fail[i]=len[i]=cnt[i]=0;
		}
		puts("");
	}
}

 

 

 

 

练习5 Luogu P3649 APIO2014 回文串

给你一个由小写拉丁字母组成的字符串 s。我们定义 s 的一个子串的存在值为这个子串在 s 中出现的次数乘以这个子串的长度。对于给你的这个字符串 s,求所有回文子串中的最大存在值。

建出回文树后在fail树上统计一下结果即可.

#include <iostream>
#include <string.h>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int n, tot, last, fail[N], len[N];
int cnt[N], ch[N][26];
char s[N];

int getfail(int x, int n) {
	while (s[n-len[x]-1]!=s[n]) x=fail[x];
	return x;
}

int main() {
	scanf("%s", s+1);
	s[0]='#',fail[0]=1,last=0;
	len[0]=0,len[1]=-1,tot=1;
	n = strlen(s+1);
	REP(i,1,n) {
		s[i] -= 'a';
		int p = getfail(last,i);
		if (!ch[p][s[i]]) {
			len[++tot] = len[p]+2;
			fail[tot]=ch[getfail(fail[p],i)][s[i]];
			ch[p][s[i]]=tot;
		}
		++cnt[last=ch[p][s[i]]];
	}
	ll ans = 0;
	PER(i,1,tot) cnt[fail[i]]+=cnt[i],ans=max(ans,(ll)cnt[i]*len[i]);
	printf("%lld\n", ans);
}

 

练习6 hdu 5157 Harry and magic string

给定字符串, 求所有不相交的回文串对数.

回文树统计出每个前后缀的回文串个数.

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int n, m, tot, cnt, last, fac[N];
int fail[N], len[N], ch[N][26], num[N];
ll sum[N];
char s[N], ss[N];

int getfail(int x) {
	while (ss[cnt-len[x]-1]!=ss[cnt]) x=fail[x];
	return x;
}
int insert(int c) {
	ss[++cnt] = c;
	int p = getfail(last);
	if (!ch[p][c]) {
		len[++tot] = len[p]+2;
		fail[tot]=ch[getfail(fail[p])][c];
		ch[p][c]=tot;
		num[tot]=num[fail[tot]]+1;
	}
	last = ch[p][c];
	return num[last];
}
void clear() {
	REP(i,0,tot) {
		memset(ch[i],0,sizeof ch[0]);
		num[i]=len[i]=fail[i]=0;
	}
	ss[0]='#',fail[0]=1,last=0;
	len[0]=0,len[1]=-1,tot=1,cnt=0;
}

int main() {
	while (~scanf("%s", s+1)) {
		n = strlen(s+1);
		clear();
		REP(i,1,n) { 
			s[i]-='a';
			sum[i] = sum[i-1]+insert(s[i]);
		}
		clear();
		ll ans = 0;
		PER(i,1,n) ans += (ll)sum[i-1]*insert(s[i]);
		printf("%lld\n", ans);
	}
}

 

转载于:https://www.cnblogs.com/uid001/p/10946118.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
# 智慧旅游解决方案摘要 智慧旅游解决方案旨在通过新一代信息网络技术和装备,实现旅游服务、管理、营销和体验的智能化。该方案响应国家政策背景,如国家旅游局和工业信息化部的指导意见,以及国家发改委的发展规划,强调数字化、网络化、智能化在旅游业的应用,推动5G和移动互联网技术在旅游领域的创新应用。 方案的建设目标围绕“一个中心、四个方面、五大平台”展开,即以智慧旅游数据中心为核心,面向服务、管理、商务和营销构建智慧景区管理平台、智慧旅游服务平台、智慧旅游商务平台和智慧旅游营销平台。这五大平台将整合全域旅游资源,提升旅游设施,拓展旅游空间,融合旅游产业链,提升旅游服务,定制旅游产品,推进旅游改革。 建设内容涵盖了整体架构的构建,包括智慧服务、智慧管理、电子商务和智慧营销等方面。通过云计算、人工智能、大数据、物联网、5G等技术,实现“云-管-端”服务能力,打造集时间、空间、层次为一体的体验平台。此外,还包括智慧景区管理平台的多个子系统,如视频监控、应急指挥调度、流量监测、舆情监督、线路SOS一键呼救、GIS人车调度、停车场管理、语音广播、环境监测管理、多媒体发布、电子巡更以及指挥调度大屏建设等。 智慧旅游服务平台则包括自助票务系统、人脸识别、扫码购票、景区门户网站、机游、WIFI覆盖系统、数字全景VR、AI机器人、智慧座椅、智慧厕所等,旨在提升游客体验,实现景区的智能化管理和服务。通过这些服务,游客可以享受到便捷的购票、入园、导览和信息服务,同时景区管理者能够更有效地监控和管理景区运营。 智慧旅游商务平台则侧重于旅行社团队申报、电子商城、综合票务系统、分销管理系统、大会员系统和景区聚合支付系统,为旅游企业提供全面的商务服务和营销支持。这些平台和系统帮助旅游企业拓宽分销渠道,实现财务管理和订单管理,同时为游客提供便捷的支付和会员服务。 最后,智慧营销平台通过综合票务系统、分销管理系统、大会员系统和景区聚合支付系统,为旅游行业提供精准的营销工具和策略。这些工具和策略有助于整合旅游资源,拓宽销售渠道,提升游客体验,实现旅游业务的数字化和智能化。 智慧旅游解决方案通过这些综合性的技术和平台,不仅提升了游客的旅游体验,还为旅游行业的可持续发展提供了强有力的技术支持和数据驱动的决策依据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值