HDU
来源:互联网 发布:怎么js调用方法 编辑:程序博客网 时间:2024/06/04 18:56
Reincarnation
HDU - 4622Now 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(sl...r l...r), sl...r 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
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.
2bbaba53 42 22 52 41 4baaba53 33 41 43 55 5
3175813851
I won't do anything against hash because I am nice.Of course this problem has a solution that don't rely on hash.
#include <iostream>#include <cstdio>#include <string>#include <cstring>using namespace std;typedef long long LL;const int maxn = 2*2e3 + 8;string s;struct SAM{ int ch[maxn][26], pre[maxn], val[maxn]; int last, tot; void init(){ last = tot = 0; memset(ch[0], -1, sizeof ch[0]); pre[0] = -1; val[0] = 0; } int extend(int c){ int p = last, np = ++tot; val[np] = val[p] + 1; memset(ch[np], -1, sizeof ch[np]); while(~p && ch[p][c] == -1) ch[p][c] = np, p = pre[p]; if(p == -1) pre[np] = 0; else{ int q = ch[p][c]; if(val[q] != val[p] + 1){ int nq = ++tot; memcpy(ch[nq], ch[q], sizeof ch[q]); val[nq] = val[p] + 1; pre[nq] = pre[q]; pre[q] = pre[np] = nq; while(~p && ch[p][c] == q) ch[p][c] = nq, p = pre[p]; } else pre[np] = q; } last = np; return val[np] - val[pre[np]]; }} sam;int sum[maxn][maxn];int main(){ #ifdef LOCAL freopen("13.in", "r", stdin); //freopen("13.out", "w", stdout); #endif // LOCAL ios::sync_with_stdio(false); cin.tie(0); int T, n, i, j, q; cin >> T; while(T--){ cin >> s; n = s.size(); for(i = 0; i < n; i++){ sam.init(); sum[i+1][0] = 0; for(j = i; j < n; j++) sum[i+1][j+1] = sum[i+1][j] + sam.extend(s[j] - 'a'); } cin >> q; while(q--){ cin >> i >> j; cout << sum[i][j] << "\n"; } } return 0;}
0 0