hdu4622-Reincarnation(后缀自动机)
Given you a
string s consist of lower-case English letters only,denote f(s) as the number of
distinct sub-string of s.
And you have some query,each time you should
calculate f(s[l...r]), s[l...r] means the sub-string of s start from l end at
r.
denote the number of the test cases.
For each test cases,the first line
contains a string s(1 <= length of s <= 2000).
Denote the length of s
by n.
The second line contains an integer Q(1 <= Q <= 10000),denote the
number of queries.
Then Q lines follows,each lines contains two integer l,
r(1 <= l <= r <= n), denote a query.
one line.
题意: 给一个字符串长度最大2000,给出Q个查询[l,r]包含多少种连续的子串。
解析: 后缀自动机轻松过,先对查询离线排序,对于左端点相同的建立一个后缀自动
机,字符串长度最大只有2000,所以最后只用建2000个,每个sam插入的字符最多也就
2000,时间肯定是够的。
代码
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=;
struct SAM
{
int ch[maxn][];
int pre[maxn],step[maxn];
int last,id;
void init()
{
last=id=;
memset(ch[],-,sizeof(ch[]));
pre[]=-; step[]=;
}
void Insert(int c) //字符转化为数
{
int p=last,np=++id;
step[np]=step[p]+;
memset(ch[np],-,sizeof(ch[np]));
while(p!=-&&ch[p][c]==-) ch[p][c]=np,p=pre[p];
if(p==-) pre[np]=;
else
{
int q=ch[p][c];
if(step[q]!=step[p]+)
{
int nq=++id;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
step[nq]=step[p]+;
pre[nq]=pre[q];
pre[np]=pre[q]=nq;
while(p!=-&&ch[p][c]==q) ch[p][c]=nq,p=pre[p];
}
else pre[np]=q;
}
last=np;
}
int GetCnt()
{
int ret=;
for(int i=id;i>=;i--) ret+=step[i]-step[pre[i]];
return ret;
}
}sam;
char S[maxn/];
struct Ques
{
int l,r,id;
Ques(int l=,int r=,int id=):l(l),r(r),id(id){}
bool operator < (const Ques& t) const
{
if(l!=t.l) return l<t.l;
return r<t.r;
}
}q[];
int Q,ans[];
void solve()
{
sort(q,q+Q);
int last;
for(int i=;i<Q;i++)
{
if(i==||q[i].l!=q[i-].l)
{
sam.init();
last=q[i].l;
}
for(;last<=q[i].r;last++) sam.Insert(S[last]-'a');
ans[q[i].id]=sam.GetCnt();
}
for(int i=;i<Q;i++) printf("%d\n",ans[i]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",S+);
int len=strlen(S);
scanf("%d",&Q);
int l,r,id;
for(int i=;i<Q;i++)
{
scanf("%d%d",&l,&r);
q[i]=Ques(l,r,i);
}
solve();
}
return ;
}
hdu4622-Reincarnation(后缀自动机)的更多相关文章
- HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)
Reincarnation Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) P ...
- HDU 4622 Reincarnation 后缀自动机
模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747 解法参考:http://blog.csdn.net/dyx ...
- HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数. 可以用后缀数组来解决,复杂度O(n).先求出倍 ...
- HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)
Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-ca ...
- [hdu4622 Reincarnation]后缀数组
题意:给一个长度为2000的字符串,10000次询问区间[L,R]内的不同子串的个数 思路:对原串的每个前缀求一边后缀数组,询问[L,R]就变成了询问[L,n]了,即求一个后缀里面出现了多少个不同子串 ...
- Hdu 4622 Reincarnation(后缀自动机)
/* 字符串长度较小, 可以离线或者直接与处理所有区间的答案 动态加入点的时候, 因为对于其他点的parent构造要么没有影响, 要么就是在两个节点之间塞入一个点, 对于minmax的贡献没有改变 所 ...
- 【HDU4622】Reincarnation(后缀自动机)
[HDU4622]Reincarnation(后缀自动机) 题面 Vjudge 题意:给定一个串,每次询问l~r组成的子串的不同子串个数 题解 看到字符串的大小很小 而询问数太多 所以我们预处理任意的 ...
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
Reincarnation Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- Reincarnation HDU - 4622 (后缀自动机)
Reincarnation \[ Time Limit: 3000 ms\quad Memory Limit: 65536 kB \] 题意 给出一个字符串 \(S\),然后给出 \(m\) 次查询, ...
- HDU 4622 Reincarnation(后缀自动机)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4622 [题目大意] 给出一个长度不超过2000的字符串,有不超过10000个询问,问[L,R]子串 ...
随机推荐
- js高级教程第3版笔记(我的理解)陆续更新中
js基础语法'use strict'(严格模式)定义变量var object;只声明未赋值,默认值为undefined;var object1=值;声明并赋值;function fun(a){这样也叫 ...
- 探究css !important的应用之道
定义及语法: !important是CSS1就定义的语法,作用是提高指定样式规则的应用优先权. 语法格式:{ cssRule !important },即将!important写在定义的最后面, 例如 ...
- Unity3D性能优化总结
一.程序方面 01.务必删除脚本中为空或不须要的默认方法: 02.仅仅在一个脚本中使用OnGUI方法. 03.避免在OnGUI中对变量.方法进行更新.赋值,输出变量建议在Update内. 04.同一脚 ...
- SQL Profile 总结(一)
一.前提概述 在介绍SQL Profile之前,不得不说的一个工具就是SQL Tuning Advisor:这个工具是从Oracle 10g開始引入,它的任务就是分析一个指定的SQL语句,并建议怎样使 ...
- C#使用 SQLite 数据库 开发的配置过程及基本操作类,实例程序:工商银行贵金属行情查看小工具
--首发于博客园, 转载请保留此链接 博客原文地址 本文运行环境: Win7 X64, VS2010 1. SQLite 的优点: SQLite 是一款轻型数据库,开发包只有十几M, 相对于 MSS ...
- Linux下一些基本操作
一.忘记root密码 1. sudo passwd root 2. 输入新密码. 二.查看内核版本: 1.查看内核版本命令:1) cat /proc/version 2) uname -a 3) u ...
- LSI SAS 3008配置操作
配置 LSI SAS 3008 介绍LSISAS3008的配置操作. 4.1 登录CU界面 介绍登录LSISAS3008的CU配置界面的方法. 4.2 创建RAID 介绍在LSISAS3008扣卡上创 ...
- Sass混合宏、继承、占位符
混合宏-声明混合宏如果你的整个网站中有几处小样式类似,比如颜色,字体等,在 Sass 可以使用变量来统一处理,那么这种选择还是不错的.但当你的样式变得越来越复杂,需要重复使用大段的样式时,使用变量就无 ...
- [c#]asp.net开发微信公众平台(6)阶段总结、服务搭建、接入
经过前5篇,跟着一步步来的话,任何人都能搭建好一个能处理各种微信消息的框架了,总结一下最容易忽略的问题: 1.文本消息中可以使用换行符\n : 2.微信发来的消息中带的那个长整型的时间,我们完全 ...
- 解析c语言背后的汇编代码
源码 很简单的c语言代码,作用是交换两个数: #include <stdio.h> void swap(int * a, int * b) { *a = *a + *b - (*b = * ...