Reincarnation
Time Limit: 3000ms
Memory Limit: 65536KB
This problem will be judged on HDU. Original ID: 462264-bit integer IO format: %I64d Java class name: Main
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 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.
Source
解题:据说是CLJ的题
后缀自动机求某个区间子串的个数
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 5010; 4 int ret; 5 struct node { 6 int f,len,son[26]; 7 void init() { 8 memset(son,-1,sizeof son); 9 len = 0; 10 f = -1; 11 } 12 }; 13 struct SAM { 14 node e[maxn<<1]; 15 int tot,last; 16 int newnode(int len = 0) { 17 e[tot].init(); 18 e[tot].len = len; 19 return tot++; 20 } 21 void init() { 22 tot = last = 0; 23 newnode(); 24 } 25 void extend(int c) { 26 int p = last,np = newnode(e[p].len + 1); 27 while(p != -1 && e[p].son[c] == -1) { 28 e[p].son[c] = np; 29 p = e[p].f; 30 } 31 if(p == -1) { 32 e[np].f = 0; 33 ret += e[np].len - e[0].len; 34 } else { 35 int q = e[p].son[c]; 36 if(e[p].len + 1 == e[q].len) { 37 e[np].f = q; 38 ret += e[np].len - e[q].len; 39 } else { 40 int nq = newnode(); 41 e[nq] = e[q]; 42 e[q].f = e[np].f = nq; 43 e[nq].len = e[p].len + 1; 44 ret += e[np].len - e[e[np].f].len; 45 while(p != -1 && e[p].son[c] == q) { 46 e[p].son[c] = nq; 47 p = e[p].f; 48 } 49 } 50 } 51 last = np; 52 } 53 } sam; 54 int ans[2010][2010]; 55 char str[maxn]; 56 int main() { 57 int kase,q,L,R; 58 scanf("%d",&kase); 59 while(kase--) { 60 scanf("%s",str); 61 for(int i = 0; str[i]; ++i) { 62 sam.init(); 63 ret = 0; 64 for(int j = i; str[j]; ++j) { 65 sam.extend(str[j] - 'a'); 66 ans[i][j] = ret; 67 } 68 } 69 scanf("%d",&q); 70 while(q--) { 71 scanf("%d%d",&L,&R); 72 printf("%d ",ans[L-1][R-1]); 73 } 74 } 75 return 0; 76 }