YBTOJ:前缀询问(trie树)

本文介绍了一种利用Trie树解决字符串中最大间隔的问题。文章首先阐述了题目要求,即找出所有子串中,任意两个不相同字符的最大间隔。接着,通过建立Trie树,并在插入字符串时沿途记录最大间隔,最终实现快速查询。代码部分展示了如何构建Trie树并进行查询,对于给定的测试用例,能够有效计算出最大间隔。
摘要由CSDN通过智能技术生成

题目描述

请添加图片描述

解析

(没有做出来,这个ans的处理方式其实也不难想…qwq)

考虑把T都作为模板串加入trie树
加入每个模板串自然就是按照i顺序的
所以我们在插入t的时候沿途标记一下
新出现的未标记的i的间隔就是当前的i与上一次的标记的差-1
在其中一直取max即可得到最大间隔
不要忘记还有一个间隔是n-最后的标记值!

预处理完trie树后就简单了
让s在trie树上跑,跑到尾就返回尾的ans值即可
如果跑一半失配了说明没有t符合条件,直接返回n即可

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef unsigned long long ull;
const int N = 6e6+100;
const int M=1e6+10;
const ll mod=199907210507;
int n,m;
int tr[N][4],tot=1,ans[N],id[N];
char s[N];
void build(int k){
	int l=strlen(s+1),p=1;
	for(int i=1;i<=l;i++){
		int a=s[i]-'a'+1;
		if(!tr[p][a]) tr[p][a]=++tot;
		p=tr[p][a];
		ans[p]=max(ans[p],k-id[p]-1);
		id[p]=k;
	}
}

int ask(){
	int l=strlen(s+1),p=1;
	for(int i=1;i<=l;i++){
		int a=s[i]-'a'+1;
		if(!tr[p][a]) return n;
		p=tr[p][a];
	}
	return ans[p];
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf(" %s",s+1);
		build(i);
	}
	for(int i=1;i<=tot;i++){
		ans[i]=max(ans[i],n-id[i]);
	}
	for(int i=1;i<=m;i++){
		scanf(" %s",s+1);
		printf("%d\n",ask());
	}
	return 0;
}
/*
9 6 10
5 6 2 10 10 7 3 2 9 
1 4 4 3 2 1

6 4 10
3 5 2 7 1 9
3 8 2 10
*/

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值