HDU 4622 求解区间字符串中的不同子串的个数
题目大意:
给定一个长度<2000的串,再给最多可达10000的询问区间,求解区间字符串中的不同子串的个数
这里先考虑求解一整个字符串的所有不同子串的方法
对于后缀自动机来说,我们动态往里添加一个字符,每次添加一个字符进去,我们只考虑那个生成的长度为当前长度的后缀自动机的节点
那么这个节点可接收的字符串的个数就是( p->l - p->f->l ),也就是以当前点为最后节点所能得到的与之前不重复的子串的个数
那么这个问题就很好解决了,共2000个位置,以每一个位置为起点构建一次后缀自动机,一直构建到最后一个字符,过程中不断记录所能得到的子串个数
把这个个数动态保存到f[][]数组中
那么打好了表,最后询问的时候,直接访问这个f[][]即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
#define N 2005
#define M 26
struct SamNode{
SamNode *son[M] , *f;
int l;
void init(){
for(int i= ; i<M ; i++) son[i] = NULL;
f=NULL , l=;
}
}sam[N<<] , *root , *last; int cnt , f[N][N] , ret;
char s[N] ; void init(){
sam[].init();
root = last = &sam[cnt=];
} void add(int x)
{
SamNode *p = &sam[++cnt] , *jp=last;
p->init();
p->l = jp->l+;
last = p;
for(; jp&&!jp->son[x] ; jp=jp->f) jp->son[x] = p;
if(!jp) p->f = root;
else{
if(jp->l+ == jp->son[x]->l) p->f = jp->son[x];
else{
SamNode *r = &sam[++cnt] , *q = jp->son[x];
r->init();
*r = *q; r->l = jp->l+;
p->f = q->f = r;
for( ; jp&&jp->son[x]==q ; jp=jp->f) jp->son[x] = r;
}
}
ret += p->l-(p->f->l);
} void solve()
{
int len = strlen(s);
for(int i= ; i<len ; i++){
ret = ;
init();
for(int j=i ; j<len ; j++){
add(s[j]-'a');
f[i][j] = ret;
}
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
scanf("%s", s);
int m , l , r;
scanf("%d" , &m);
solve();
while(m--){
scanf("%d%d" , &l , &r);
printf("%d\n" , f[l-][r-]);
}
}
return ;
}
HDU 4622 求解区间字符串中的不同子串的个数的更多相关文章
- Java:判断字符串中包含某字符的个数
Java:判断字符串中包含某字符的个数 JAVA中查询一个词在内容中出现的次数: public int getCount(String str,String key){ if(str == null ...
- JAVA判断字符串中某个字符存在的个数
/** * 判断字符串中某个字符存在的个数 * @param str1 完整字符串 * @param str2 要统计匹配个数的字符 * @return */ public static int co ...
- 【Java】获取两个字符串中最大相同子串
题目 获取两个字符串中最大相同子串 前提 两个字符串中只有一个最大相同子串 解决方案 public class StringDemo { public static void main(String[ ...
- 萌新笔记——Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)
最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对"基数"以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了"HyperLo ...
- POJ 3294 二分找超过一半字符串中存在的子串
题目大意: 给定n个字符串,求出现在不小于k/2个字符串中的最长子串. 二分找对应子串长度的答案,将所有字符串链接成一个长字符串求后缀数组,记录每一个位置本属于第几个字符串,利用height查询的时候 ...
- C语言strstr()函数:返回字符串中首次出现子串的地址
今天又学到了一个函数 头文件:#include <string.h> strstr()函数用来检索子串在字符串中首次出现的位置,其原型为: char *strstr( char *s ...
- java 获得字符串中最大重复子串长度
参考:http://blog.csdn.net/csdn_yaobo/article/details/50338025 要找一串字符串中,重复的字串长度,.例如ABCX1&ABC,中ABC重复 ...
- Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)
最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对“基数”以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了“HyperLogLog”,从而引出了Card ...
- 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。java算法
知识点一:equalsIgnore 1.使用equals( )方法比较两个字符串是否相等.它具有如下的一般形式: boolean equals(Object str) 这里str是一个用来与调用字符串 ...
随机推荐
- Service 与 Thread 的区别
很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来解释一下. 1). Thread:Thre ...
- jQuery DOM基础
jQuery DOM基础 1.对元素内容的获取和修改: 表单用value(),普通元素用html()和text(). html() html(value)设置和获取html内容,有html标签会自动 ...
- PHP 链式操作
所谓链式操作最简单的理解就是 操作完毕之后再返回对象$this 想必大家工作中基本都快用烂了得东西. 下面就是一个链式操作MYSQL数据库类. 最常见的链式操作 每一个方法操作之后,返回一个对象,直到 ...
- Oracle一个用户查询另一个用户的表数据
1.两个用户是在不同的库,需要建立dblink 2.属于同一个库的不同用户 1)方法一:使用"用户名."的方式访问 例如:要从USER1账号访问USER2中的表TABLE2 A. ...
- 实体类实现Parcelable(包含boolean类型)
实体类实现Parcelable接口需要实现方法: public ExtSignClockEntity(Parcel in) { timeMess = in.readString(); repeatMe ...
- foreach 相关
20 Nov 08 深入理解PHP原理之foreach 作者: Laruence( ) 本文地址: http://www.laruence.com/2008/11/20/630.html 转载请注 ...
- Canu Tutorial(canu指导手册)
链接:Canu Tutorial Canu assembles reads from PacBio RS II or Oxford Nanopore MinION instruments into u ...
- python 暴力破解密码脚本
python 暴力破解密码脚本 以下,仅为个人测试代码,环境也是测试环境,暴力破解原理都是一样的, 假设要暴力破解登陆网站www.a.com 用户 testUser的密码, 首先,该网站登陆的验证要支 ...
- 用NAN简化Google V8 JS引擎的扩展
通过C++扩展Google V8 JS引擎的文章很多,Google V8 JS带的例子也容易明白.但是大部分文章都是Hello World型的,真正使用时发现处处是坑.扩展V8最经典的例子就是node ...
- Link Collecting
----------------------------------\ ACM入门总结之常见输入输出格式暨hdu1089~1096 题解,谨献给对acm感兴趣的新人 - 博客频道 - CSDN.NET ...