Problem Description
Now you are back,and have a task to do:
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.
 
Input
The first line contains integer T(1<=T<=5),
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.
 
Output
For each test cases,for each query,print the answer in
one line.
 
Sample Input
2
bbaba
5
3 4
2 2
2 5
2 4
1 4
baaba
5
3 3
3 4
1 4
3 5
5 5
 
Sample Output
3
1
7
5
8
1
3
8
5
1
 
 

题意: 给一个字符串长度最大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(后缀自动机)的更多相关文章

  1. HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) P ...

  2. HDU 4622 Reincarnation 后缀自动机

    模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747 解法参考:http://blog.csdn.net/dyx ...

  3. HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数. 可以用后缀数组来解决,复杂度O(n).先求出倍 ...

  4. HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)

    Problem Description Now you are back,and have a task to do: Given you a string s consist of lower-ca ...

  5. [hdu4622 Reincarnation]后缀数组

    题意:给一个长度为2000的字符串,10000次询问区间[L,R]内的不同子串的个数 思路:对原串的每个前缀求一边后缀数组,询问[L,R]就变成了询问[L,n]了,即求一个后缀里面出现了多少个不同子串 ...

  6. Hdu 4622 Reincarnation(后缀自动机)

    /* 字符串长度较小, 可以离线或者直接与处理所有区间的答案 动态加入点的时候, 因为对于其他点的parent构造要么没有影响, 要么就是在两个节点之间塞入一个点, 对于minmax的贡献没有改变 所 ...

  7. 【HDU4622】Reincarnation(后缀自动机)

    [HDU4622]Reincarnation(后缀自动机) 题面 Vjudge 题意:给定一个串,每次询问l~r组成的子串的不同子串个数 题解 看到字符串的大小很小 而询问数太多 所以我们预处理任意的 ...

  8. HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  9. Reincarnation HDU - 4622 (后缀自动机)

    Reincarnation \[ Time Limit: 3000 ms\quad Memory Limit: 65536 kB \] 题意 给出一个字符串 \(S\),然后给出 \(m\) 次查询, ...

  10. HDU 4622 Reincarnation(后缀自动机)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4622 [题目大意] 给出一个长度不超过2000的字符串,有不超过10000个询问,问[L,R]子串 ...

随机推荐

  1. 多次绑定click及ajax提交常用方法

    <script> $(document).ready(function() { //绑定click $(".exchange_ecv").bind("clic ...

  2. INSERT command denied to user

    问题分析: 网站运行突然出现下面的 MySQL 错误: 645297 [http-88-13] ERROR com.mes.cart.dao.impl.CartDAOImpl - CartDAOImp ...

  3. firefox关于about:config的常用配置

    about:config是火狐的设置页面,火狐提供了不少高级设置选项在这里以便让你可以更加详细地控制火狐的运行方式.(官方不推荐用户手工修改about:config的设置.所以,如果你对于你想修改的内 ...

  4. Cocos2D-x权威指南: CCNode类方法:

    5.1.4 画图节点CCNode和图层CCLayer CCNode中提供的方法,在public块中的方法主要有下面几个部分: 1.针对节点显示的属性信息读写 2.针对节点变换的属性信息读写 3.针对子 ...

  5. Openstack 二次开发之:在windows 环境下编译Openstack-java-sdk

    在windows环境下使用maven对openstack-java-sdk进行编译 编译源文件 下载源代码 git clonehttps://github.com/woorea/openstack-j ...

  6. 使用Eclipse生成自动生成apk

    使用Eclipse生成自动生成apk     在eclipse的Preferences -> Android -> Build中有一项“Skip packaging and dexing ...

  7. [ES6] Module export

    Default export: Default export is easy way to export a function to outside module. //flash-message.j ...

  8. 只响应ccTouchBegan的问题

    在Touch事件中,ccTouchBegan有一个返回值,而这一个返回值则决定了是否会继续响应ccTouchMoved,ccTouchEnded. 如果没有返回true的话,则直接会结束此Touch事 ...

  9. 模拟jquery封装选择器

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 腾讯云(centos)上安装apache

    安装 yun install httpd 随系统自启动 chkconfig httpd on 修改/etc/httpd/conf/httpd.conf文件 #修改WWW目录为自己的目录 Dcoumen ...