HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)

2024-02-19 20:38

本文主要是介绍HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622


这个题目开始是用后缀数组来做的,但是这个题目对后缀数组时间卡的很紧,后来看解题报告说是用后缀自动机搞定的,想想也是CLJ出题怎么会没有后缀

自动机呢

其实这个题目字符串长度不算长2000,但是查询可以达到10000次,如果每次查询都重新建立后缀自动机来计算不同子串的个数的话会超时,但是考虑到后

缀自动机的构造过程的一个在线的,所以我们就考虑能不能先把要查询的区间排序,然后按照左边界排序,左边界相同的按照右边界从小到达排序,这样,

在构造后缀自动机的时候现在的就可以在先前的基础上构造了(一定是后一个的l和前一个的l相等,如果不相等就重新构造),这样我们最多构造两千次

这样复杂度就够了!


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 2100
struct point
{point *father,*next[26];int val;
}po[maxn*3],*root,*tail;
int tot,len,ans[110000];
char str[maxn];
struct query
{int l,r;int num;
}rec[11000];
void add(int c,int l)
{point *p=tail,*np=&po[tot++];np->val=l;while(p&&p->next[c]==NULL)p->next[c]=np,p=p->father;if(p==NULL) np->father=root;else{point *q=p->next[c];if(p->val+1==q->val) np->father=q;else{point *nq=&po[tot++];*nq=*q;nq->val=p->val+1;np->father=q->father=nq;while(p&&p->next[c]==q) p->next[c]=nq,p=p->father;}}tail=np;
}
bool cmp(const query &a,const query &b)
{if(a.l != b.l)return a.l < b.l;if(a.r !=b.r)return a.r < b.r;return a.num < b.num;
}
int start()
{memset(po,0,sizeof(po));len=1,tot=1;root=tail=&po[0];return 0;
}
int find_ans()//后缀自动机求不同子串个数
{int i,j,ans=0;for(i=tot-1;i>0;i--)ans+=po[i].val-po[i].father->val;return ans;
}
int main()
{int t,i,j,k,n;scanf("%d",&t);while(t--){scanf("%s",str+1);scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d%d",&rec[i].l,&rec[i].r);rec[i].num=i;}sort(rec+1,rec+1+n,cmp);start();j=1;for(i=1;i<=n;i++){if(i==1 || rec[i].l==rec[i-1].l){for(j;j<=rec[i].r;j++)add(str[j]-'a',len++);}else{start();for(j=rec[i].l;j<=rec[i].r;j++)add(str[j]-'a',len++);}ans[rec[i].num]=find_ans();}for(i=1;i<=n;i++)printf("%d\n",ans[i]);}return 0;
}


这篇关于HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/725898

相关文章

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Python在固定文件夹批量创建固定后缀的文件(方法详解)

《Python在固定文件夹批量创建固定后缀的文件(方法详解)》文章讲述了如何使用Python批量创建后缀为.md的文件夹,生成100个,代码中需要修改的路径、前缀和后缀名,并提供了注意事项和代码示例,... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果5.

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi