Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 4673 Accepted Submission(s): 1916
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
题意:给出一个字符串和q次询问,每次询问[l,r]区间内不同子串的个数
预处理出所有区间的不同子串个数,暴力每个区间,对于每个区间的字符串构建后缀自动机求出子串个数,然后去重
#include
#include
#include
using namespace std;
const int maxm = 10005;
struct node
{
int len, link;
int Next[26];
}st[maxm];
int cnt, last, ans[2005][2005];
char str[maxm];
void init()
{
cnt = last = 0;
memset(st, 0, sizeof(st));
st[cnt].link = -1;
cnt++;
}
void insert(char ch)
{
int p = last, now = cnt++, rev;
st[now].len = st[last].len + 1;
while (p != -1 && !st[p].Next[ch - 'a'])
{
st[p].Next[ch - 'a'] = now;
p = st[p].link;
}
if (p == -1)
st[now].link = 0;
else
{
int q = st[p].Next[ch - 'a'];
if (st[q].len == st[p].len + 1)
st[now].link = q;
else
{
rev = cnt++;
st[rev] = st[q];
st[rev].len = st[p].len + 1;
while (p != -1 && st[p].Next[ch - 'a'] == q)
st[p].Next[ch-'a'] = rev, p = st[p].link;
st[q].link = st[now].link = rev;
}
}
last = now;
}
int main()
{
int n, i, j, k, sum, t, l, r;
scanf("%d", &t);
while (t--)
{
scanf("%s", str + 1);
k = strlen(str + 1);
memset(ans, 0, sizeof(ans));
for (i = 1;i <= k;i++)
{
init();
for (j = i;j <= k;j++)
{
insert(str[j]);
//printf("%d %d\n", st[last].len,last);
ans[i][j] = ans[i][j - 1] + st[last].len - st[st[last].link].len;
}
}
scanf("%d", &k);
while (k--)
{
scanf("%d%d", &l, &r);
printf("%d\n", ans[l][r]);
}
}
return 0;
}