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]子串 ...
随机推荐
- spring中获取Bean
在测试类中我们获取已经装配给容器的Bean的方法是通过ApplicationContext,即 ApplicationContext ac=new ClassPathXmlApplicationCon ...
- Mac phpstorm破解版安装(简单,有效)
如果是公司作为商业用途的,还是希望你能购买正版的,如果是苦逼的穷学生,亦或是我这样的苦逼码农,那就往下看, 之前有个只需要在"License server address"里输入 ...
- 获取WebView加载HTML时网页中的内容
main.xml如下: [html] view plaincopy <RelativeLayout xmlns:android="http://schemas.android.com/ ...
- 在Ubuntu下构建Bullet以及执行Bullet的样例程序
在Ubuntu下构建Bullet以及执行Bullet的样例程序 1.找到Bullet的下载页,地址是:https://code.google.com/p/bullet/downloads/list 2 ...
- Excel02-快速无误输入多个零
第一步:设置单元格格式-->小数位数为0,货币符号为¥ 第二步:在单元格输入数据:1**5回车即显示为¥100,000 **N 表示后面有N个零,会自动加入我们设置的货币符号¥ 这对我们在输入巨 ...
- Python-xml解析常用方法简介
[XML几种解析方法] 常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,使用场合自然也就不同. Python有三种方法解析XML: SAX,DOM,以及ElementTree ...
- linux stat命令
在Linux中,文件没有“创建时间”这个说法.Linux中的文件的时间属性只有三个:atime(Access time).mtime(Modified time).ctime(Change time) ...
- 内容观察者 ContentObserver 监听短信、通话记录数据库 挂断来电
Activity public class MainActivity extends ListActivity { private TextView tv_info; private ...
- XAML 名称范围 (x:) 语言特性
本节介绍为 Windows 运行时实现的 XAML 语言特性的参考信息. 本部分内容 主题 描述 x:Class 属性 配置 XAML 编译,在标记和代码隐藏之间连接分部类.代码分部类在一个独立的代码 ...
- spring-security 登陆认证之初次探究
首先,希望还对 spring-security框架完全不懂的新手 下载下Git源码. 引入到项目中.这个短文就是边看源码边聊的.也会启动下项目验证自己的推想. 一.登陆认证的登陆配置项 <for ...