Reincarnation
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 3684 Accepted Submission(s): 1441
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.
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.
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 1HintI won't do anything against hash because I am nice.Of course this problem has a solution that don't rely on hash.
Author
WJMZBMR
Source
Recommend
zhuyuanchen520 | We have carefully selected several similar problems for you:
6032
6031
6030
6029
6028
【分析】
后缀自动机第一题...
细节出错被卡成了zz...qwq
我们可以以每个位置为开头跑len编自动机,然后把用ans[i][j]记录答案,O(1)查询。
ans[i][j]=ans[i][j-1]+step[np]-step[pre[np]](防止相同的前缀子串重复计数)
【代码】
//hdu 4622 Reincarnation
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=2005;
char s[mxn];
int n,m,T,p,q,np,nq,len,root,last,tot;
int step[mxn<<1],son[mxn<<1][30],pre[mxn<<1],ans[mxn][mxn];
inline void sam(int S)
{
int i,j;
np=root=tot=1;
M(step),M(son),M(pre);
fo(i,S,len)
{
int c=s[i]-'a'+1;
p=np;
step[np=(++tot)]=step[p]+1;
while(p && !son[p][c])
son[p][c]=np,p=pre[p];
if(!p)
{
pre[np]=root;
ans[S][i]=ans[S][i-1]+step[np];
continue;
}
q=son[p][c];
if(step[p]+1==step[q])
pre[np]=q;
else
{
step[nq=(++tot)]=step[p]+1;
fo(j,1,26) son[nq][j]=son[q][j];
pre[nq]=pre[q];
pre[q]=pre[np]=nq;
while(p && son[p][c]==q)
son[p][c]=nq,p=pre[p];
}
ans[S][i]=ans[S][i-1]+step[np]-step[pre[np]];
}
}
int main()
{
int i,j,l,r;
scanf("%d",&T);
while(T--)
{
M(ans);
scanf("%s",s+1);
len=strlen(s+1);
scanf("%d",&n);
fo(i,1,len) sam(i);
while(n--)
{
scanf("%d%d",&l,&r);
printf("%d\n",ans[l][r]);
}
}
return 0;
}