HDU 4622 Reincarnation

Reincarnation

Time Limit: 3000ms
Memory Limit: 65536KB
This problem will be judged on HDU. Original ID: 4622
64-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.
 

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.
 

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 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/4790198.html