# Reincarnation

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 843    Accepted Submission(s): 283

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.

Source

Recommend
zhuyuanchen520

N<=2000.

  1 #include <stdio.h>
2 #include <string.h>
3 #include <algorithm>
4 #include <iostream>
5 using namespace std;
6
7 const int CHAR = 26;
8 const int MAXN = 2020;
9 struct SAM_Node
10 {
11     SAM_Node *fa,*next[CHAR];
12     int len;
13     int id,pos;
14     SAM_Node(){}
15     SAM_Node(int _len)
16     {
17         fa = 0;
18         len = _len;
19         memset(next,0,sizeof(next));
20     }
21 };
22 SAM_Node SAM_node[MAXN*2], *SAM_root, *SAM_last;
23 int SAM_size;
24 SAM_Node *newSAM_Node(int len)
25 {
26     SAM_node[SAM_size] = SAM_Node(len);
27     SAM_node[SAM_size].id = SAM_size;
28     return &SAM_node[SAM_size++];
29 }
30 SAM_Node *newSAM_Node(SAM_Node *p)
31 {
32     SAM_node[SAM_size] = *p;
33     SAM_node[SAM_size].id = SAM_size;
34     return &SAM_node[SAM_size++];
35 }
36 void SAM_init()
37 {
38     SAM_size = 0;
39     SAM_root = SAM_last = newSAM_Node(0);
40     SAM_node[0].pos = 0;
41 }
43 {
44     SAM_Node *p = SAM_last, *np = newSAM_Node(p->len+1);
45     np->pos = len;
46     SAM_last = np;
47     for(;p && !p->next[x];p = p->fa)
48         p->next[x] = np;
49     if(!p)
50     {
51         np->fa = SAM_root;
52         return;
53     }
54     SAM_Node *q = p->next[x];
55     if(q->len == p->len + 1)
56     {
57         np->fa = q;
58         return;
59     }
60     SAM_Node *nq = newSAM_Node(q);
61     nq->len = p->len + 1;
62     q->fa = nq;
63     np->fa = nq;
64     for(;p && p->next[x] == q;p = p->fa)
65         p->next[x] = nq;
66 }
67 void SAM_build(char *s)
68 {
69     SAM_init();
70     int len = strlen(s);
71     for(int i = 0;i < len;i++)
73 }
74
75 int Q[MAXN][MAXN];
76 char str[MAXN];
77 int main()
78 {
79     int T;
80     scanf("%d",&T);
81     while(T--)
82     {
83         scanf("%s",str);
84         int n = strlen(str);
85         memset(Q,0,sizeof(Q));
86         for(int i = 0;i < n;i++)
87         {
88             SAM_init();
89             for(int j = i;j < n;j++)
90             {
92             }
93             for(int j = 1;j < SAM_size;j++)
94             {
95                 Q[i][SAM_node[j].pos-1+i]+=SAM_node[j].len - SAM_node[j].fa->len;
96             }
97             for(int j = i+1;j < n;j++)
98                 Q[i][j] += Q[i][j-1];
99         }
100         int M;
101         int u,v;
102         scanf("%d",&M);
103         while(M--)
104         {
105             scanf("%d%d",&u,&v);
106             u--;v--;
107             printf("%d\n",Q[u][v]);
108         }
109     }
110     return 0;
111 }

posted on 2013-08-06 09:18  kuangbin  阅读(...)  评论(...编辑  收藏

• 随笔 - 940
• 文章 - 0
• 评论 - 582
• 引用 - 0
JAVASCRIPT: