[HDU4622]Reincarnation-后缀自动机
来源:互联网 发布:腾讯微云mac 设置同步 编辑:程序博客网 时间:2024/05/11 20:37
Reincarnation
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
Hint
I won't do anything against hash because I am nice.Of course this problem has a solution that don't rely on hash.
是谁说这题是后缀自动机入门题的……想了好久……
//掀桌.jpg┏┻┻┻┻┻┻┻┓ | |┃ ┏┓ ┏┓ ┃ | |┃ ┗┛ A┗┏━┓ ┏━┓━━┻━━━━━━━┻━━━┗━━━━━┗━┛ ┗━┛ | |
这真的是一道入门题???而不是一道进阶题???
我还是太弱了╮( ̄▽ ̄”)╭~~
思路:
由于咱水平有限,后缀自动机在这题只是负责数数的……
思路是预处理,对于原串每一个后缀建一次自动机。
由于自动机的性质,加一个点增加的方案数就是以该点为后缀的子串个数。
所以爆枚起点(0-n)并对每一个起点建自动机。
这时每插入一个新节点就能处理出从当前起点到当前新节点的方案数了。
预处理出表后直接查表即可。
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;const int N=5233;inline int read(){ int x=0; char ch=getchar(); while(ch<'0' || '9'<ch)ch=getchar(); while('0'<=ch && ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x;}int ans[2333][2333];struct SAM{ int next[N][26],fa[N],len[N],cnt[N]; int pool,u; void init() { pool=u=1; memset(next,0,sizeof(next)); memset(len,0,sizeof(len)); memset(cnt,0,sizeof(cnt)); memset(fa,0,sizeof(fa)); cnt[pool]=1; } int insert(int v) { int now=++pool; len[now]=len[u]+1; while(!next[u][v] && u) cnt[now]+=cnt[u],next[u][v]=now,u=fa[u]; if(!u) fa[now]=1; else { int q=next[u][v]; if(len[q]==len[u]+1) fa[now]=q; else { int newq=++pool; memcpy(next[newq],next[q],sizeof(next[q])); len[newq]=len[u]+1; fa[newq]=fa[q]; cnt[newq]=0; fa[now]=fa[q]=newq; while(next[u][v]==q && u) { cnt[next[u][v]]-=cnt[u]; cnt[newq]+=cnt[u]; next[u][v]=newq,u=fa[u]; } } } u=now; return now; }}koishi;int main(){ int T=read(); char s[N]; while(T--) { scanf("%s",&s); int len=strlen(s); for(int i=0;i<len;i++) { koishi.init(); for(int j=i;j<len;j++) { koishi.insert(s[j]-'a'); ans[i][j]=koishi.cnt[koishi.u]; } for(int j=i+1;j<len;j++) ans[i][j]+=ans[i][j-1]; } int q=read(); while(q--) { int a=read(),b=read(); printf("%d\n",ans[a-1][b-1]); } } return 0;}
- [HDU4622]Reincarnation 后缀自动机
- [HDU4622]Reincarnation-后缀自动机
- 【后缀自动机】HDU4622[Reincarnation]题解
- HDU4622(后缀自动机)
- hdu4622 后缀自动机 模板
- 后缀自动机hdu4622
- HDU4622--Reincarnation
- hdu 4622 Reincarnation (后缀自动机)
- hdu 4622 Reincarnation (后缀自动机)
- HDU 4622 Reincarnation 后缀自动机
- Hdu 4622 Reincarnation 后缀数组/后缀自动机
- Reincarnation hdu4622 hash解法
- HDU 4622 Reincarnation(后缀自动机)
- HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)
- hdu 4622 Reincarnation(后缀数组|后缀自动机|KMP)
- HDU 4622 Reincarnation 后缀数组 或 后缀自动机
- hdu 4622 Reincarnation(后缀自动机,入门级)
- [后缀自动机 模板题 || 字符串Hash] HDU 4622 Reincarnation
- keil4如何将数组清空
- ToLua SimpleFramework NGUI/UGUI基础知识[3]
- css选择器兼容性
- 蓝桥杯历届试题-城市建设 (最小生成树)
- 第六章——异常
- [HDU4622]Reincarnation-后缀自动机
- 这是一个美丽的扯
- ToLua SimpleFramework NGUI/UGUI基础知识[4]
- [SPOJ1811]Longest Common Substring-后缀自动机
- HBase学习之HRegionServer概述
- Linux之网络命令学习
- ToLua SimpleFramework NGUI/UGUI基础知识[5]
- Spring MVC注解 @Repository、@Service、@Controller和@Component @Resource和@Autowired @RequestParam
- [工具分享]wingide6 for linux 算号代码keygen