Problem Descriptionnow You is Back,and has a task to do:
Given you a string s consist of lower-case 中文版 letters Only,denote F (s) as the number of distinct sub-string of S.
And you have some query,each time should calculate f (s[l ... R]), S[l ... R] means the sub-string of S start from L end at R.
Inputthe 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 the integer l, r (1 <= l <= r <= N), denote a query.
Outputfor each test cases,for query,print the answer on one line.
Sample Input
2bbaba53 4baaba53 33 41 43 55 5
Sample Output
3175813851Hint I won ' t do anything against hash because I am nice. Of course this problem have a solution that don ' t rely on hash.
Authorwjmzbmr
Source2013 multi-university Training Contest 3
Recommendzhuyuanchen520 | We have carefully selected several similar problems for you:5279 5278 5277 5276 5275
Test instructions: Finding the number of different substrings in an interval
Idea: In the paper there are the number of different substrings of the whole string, we can extend to this problem for the whole string, our method is all the substring minus all the height value, and the height is LCP so for a certain interval, we only ask for all the suffixes contained in this interval, And then subtract the LCP between each other. The key is that we want to keep the suffix of this interval in the dictionary order
#include <iostream> #include <stdio.h> #include <string.h> #include <stack> #include <queue > #include <map> #include <set> #include <vector> #include <math.h> #include <bitset># Include <algorithm> #include <climits>using namespace std; #define LS 2*i#define RS 2*i+1#define Up (i,x,y) for (i=x;i<=y;i++) #define DOWN (i,x,y) for (i=x;i>=y;i--) #define MEM (a,x) memset (A,x,sizeof (a)) #define W (a) while (a) #define GCD (A, B) __gcd (A, b) #define LL long long#define N 2005#define MOD 1000000007#define INF 0x3f3f3f3f#define EXP 1e-8# Define rank rank1int Wa[n],wb[n],wsf[n],wv[n],sa[n];int Rank[n],height[n],s[n],a[n];char str[n],str1[n],str2[n];# Define F (x) ((x)/3+ ((x)%3==1?0:TB)) #define G (x) ((x) <TB? ( x) *3+1: ((x)-TB) *3+2)//sa: The starting position of the first bit in the dictionary sequence is sa[i]//rank in str: the suffix of str i is the longest common prefix int that is the suffix of the number of dictionaries in the dictionary order//height: Dictionary sequence I and i-1 CMP (int *r,int a,int b,int k) {return r[a]==r[b]&&r[a+k]==r[b+k];} void Getsa (int *r,int *sa,int n,int m)//n to include the 0{added at the endint i,j,p,*x=wa,*y=wb,*t; for (i=0; i<m; i++) wsf[i]=0; for (i=0; i<n; i++) wsf[x[i]=r[i]]++; for (I=1; i<m; i++) wsf[i]+=wsf[i-1]; for (i=n-1; i>=0; i--) sa[--wsf[x[i]]]=i; P=1; J=1; for (; p<n; j*=2,m=p) {for (p=0,i=n-j; i<n; i++) y[p++]=i; for (i=0; i<n; i++) if (sa[i]>=j) y[p++]=sa[i]-j; for (i=0; i<n; i++) wv[i]=x[y[i]; for (i=0; i<m; i++) wsf[i]=0; for (i=0; i<n; i++) wsf[wv[i]]++; for (I=1; i<m; i++) wsf[i]+=wsf[i-1]; for (i=n-1; i>=0; i--) sa[--wsf[wv[i]]]=y[i]; T=x; X=y; y=t; x[sa[0]]=0; for (P=1,i=1; i<n; i++) x[sa[i]]=cmp (y,sa[i-1],sa[i],j)? p-1:p++; }}void getheight (int *r,int n)//n does not save the last 0{int i,j,k=0; for (I=1; i<=n; i++) rank[sa[i]]=i; for (i=0; i<n; i++) {if (k) k--; else k=0; J=SA[RANK[I]-1]; while (R[i+k]==r[j+k]) k++; HeighT[rank[i]]=k; }}int log[n];int best[30][n];void setlog () {log[0] =-1; for (int i=1; i<n; i++) {log[i]= (i&))? LOG[I-1]:LOG[I-1] + 1; }}void RMQ (int n)//Initialize rmq{for (int i = 1; I <= n; i + +) best[0][i] = Height[i]; for (int i = 1; I <= log[n]; i + +) {int limit = n-(1<<i) + 1; for (int j = 1; J <= Limit; j + +) {Best[i][j] = min (Best[i-1][j], best[i-1][j+ (1<<i>>1) ]); }}}int LCP (int a,int b)//ask for the longest public prefix of a/b suffix {a + +; int t = log[b-a + 1]; return min (Best[t][a], best[t][b-(1<<T) + 1]);} int t,n,m;int Solve (int l,int r,int n) {int ans = (r-l+1) * (r-l+2)/2; int last =-1; int cnt = r-l+1; for (int i = 1; i<=n; i++) {if (!cnt) break; if (sa[i]<l | | sa[i]>r) continue; cnt--; if (last = =-1) {last = i; Continue } int a = last; int b = i; if (a>b) swap (A,b); int LCP = LCP (A, b); int LA = the trailing int lb = r-sa[i]+1 of the string within the r-sa[last]+1;//interval; if (la>=lb && lcp>=lb),//la contains lb, then use LA to continue the comparison, so as to keep the dictionary order, to simulate getting all the height of the interval else last = i; Ans-=min (Lcp,min (la,lb)); } return ans; int main () {int i,j,k,len,l,r; scanf ("%d", &t); Setlog (); W (t--) {scanf ("%s", str); scanf ("%d", &m); len = strlen (str); for (i = 0; i<len; i++) s[i] = str[i]-' a ' +1; S[len] = 0; Getsa (s,sa,len+1,30); GetHeight (S,len); RMQ (len); while (m--) {scanf ("%d%d", &l,&r); printf ("%d\n", Solve (L-1,r-1,len)); }} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
hdu4622:reincarnation (suffix array, to find the number of different substrings within the interval)