BZOJ 1212 HNOI2004 L语言 AC自己主动机(Trie树)+动态规划

BZOJ 1212 HNOI2004 L语言 AC自己主动机(Trie树)+动态规划

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

标题效果:给定词的列表,并m串 每个字符串q个最长前缀,这个前缀可满足拆分成一些字符串 这些字符串中存在的词汇太

再也不怕错误的数据范围……有一个很明显Trie树能解决的问题竟然被我写的AC自己主动机……

单词列表插入所有字AC主动机 每一个单词所在的节点记录这个单词的长度

然后对于每一个字符串 用f[i]表示长度为i的前缀能否拆分成单词表中的单词 跑AC自己主动机

对于每一个匹配的节点 从这个节点開始到根的fail路径上的全部len f[i]|=f[i-len]

找到最大的为1的f[i]即是答案

因为单词长度最大为10 所以直接用Trie树暴力就可以

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1050000
using namespace std;
struct Trie{
	int len;
	Trie *fail,*son[26];
	void* operator new (size_t size);
}*root,*mempool,*C;
int n,m;
char s[M];
void* Trie :: operator new (size_t size)
{
	if(C==mempool)
	{
		C=new Trie[1<<15];
		mempool=C+(1<<15);
		memset(C,0,sizeof(Trie)*(1<<15) );
	}
	return C++;
}
void Insert(Trie*&p,char *pos,int dpt)
{
	if(!p) p=new Trie;
	if(!*pos)
	{
		p->len=dpt;
		return ;
	}
	Insert(p->son[(*pos)-'a'],pos+1,dpt+1);
}
void BFS()
{
	static Trie* q[1<<16];
	static unsigned short r,h;
	int i;Trie *temp;
	for(i=0;i<26;i++)
		if(temp=root->son[i])
		{
			temp->fail=root;
			q[++r]=temp;
		}
	while(r!=h)
	{
		Trie *p=q[++h];
		for(i=0;i<26;i++)
			if(p->son[i])
			{
				temp=p->fail;
				while( temp!=root && !temp->son[i] )
					temp=temp->fail;
				if( temp->son[i] )
					temp=temp->son[i];
				p->son[i]->fail=temp;
				q[++r]=p->son[i];
			}
	}
}
int Aho_Corasick_Automaton()
{
	int i,re=0;
	Trie *p=root,*temp;
	static bool f[M];f[0]=1;
	for(i=1;s[i];i++)
	{
		f[i]=0;
		while( p!=root && !p->son[s[i]-'a'] )
			p=p->fail;
		if(p->son[s[i]-'a'])
		{
			p=p->son[s[i]-'a'];
			for(temp=p;temp!=root;temp=temp->fail)
				if(temp->len)
				{
					f[i]|=f[i-temp->len];
					if(f[i]) break;
				}
		}
		if(f[i]) re=i;
	}
	return re;
}
int main()
{
	int i;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		scanf("%s",s+1),Insert(root,s+1,0);
	BFS();
	for(i=1;i<=m;i++)
	{
		scanf("%s",s+1);
		cout<<Aho_Corasick_Automaton()<<endl;
	}
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117266.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java中类的概念

    Java中类的概念Java中类的概念类:类是一个模板,它描述一类对象的行为和状态。对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等Java中的类定义一个类的基本格式[修饰符]class类名{0到多个构造器0到多个成员变量0到多个方法0到多给初始化块}修饰符可以写publicfinalabstract或者不写,jav…

    2022年7月8日
    23
  • strstr函数用法小结

    strstr函数用法小结strstr函数原型:char*strstr(char*str1,char*str2);功能就是找出在字符串str1中第一次出项字符串str2的位置(也就是说字符串sr1中要包含有字符串str2),找到就返回该字符串位置的指针(也就是返回字符串str2在字符串str1中的地址的位置),找不到就返回空指针(就是null)。在C语言中strchr和strst

    2022年10月16日
    1
  • 主从复制、读写分离、集群、为什么要使用Redis数据库[通俗易懂]

    主从复制、读写分离、集群、为什么要使用Redis数据库[通俗易懂]一、什么是主从复制、读写分离、为什么要使用主从复制:是一种数据备份的方案。简单来说,是使用两个或两个以上相同的数据库,将一个数据库当做主数据库,而另一个数据库当做从数据库。在主数据库中进行相应操作时,从数据库记录下所有主数据库的操作,使其二者一模一样。读写分离:是一种让数据库更稳定的的使用数据库的方法。是在有从数据库的情况下使用,当主数据库进行对数据的增删改也就是写操作时,将查询的…

    2022年6月13日
    24
  • 大数据分析在职业体育应用

    大数据分析在职业体育应用大数据分析在职业体育应用(NBA)什么是大数据?举个例子,都说骑士队依赖詹姆斯,当詹姆斯在场上时,骑士队每100回合净胜对手6.9分;詹姆斯不在场,骑士队净负对手2.9分,两者之间差值为9.8分。而勇士队的库里在场上和在场下时,勇士队每100回合净胜分的差值为17分,可以说勇士队对库里的依赖甚至要更强。这样的数据才可以叫大数据,相比而言,像得分、篮板、助攻这样的技术统计简直弱爆了。大数据在N…

    2022年5月9日
    83
  • Mysql锁机制简单了解一下

    Mysql锁机制简单了解一下一锁分类(按照锁的粒度分类)Mysql为了解决并发、数据安全的问题,使用了锁机制。可以按照锁的粒度把数据库锁分为表级锁和行级锁。表级锁:Mysql中锁定粒度最大的一种锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。其锁定粒度最大,触发锁冲突的概率最高,并发度最低,MyISAM和InnoDB引擎都支持表级锁。行级锁Mysql中锁定粒…

    2022年5月1日
    42
  • oracle拼接字符串函数_拼接字符串

    oracle拼接字符串函数_拼接字符串concat(param1,param2)

    2022年9月20日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号