#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define maxn 1000000+5
#define min(a,b) ((a)<(b)?(a):(b))
char s[maxn];
int sa[maxn],h[maxn],height[maxn],rank[maxn];
int k,n;
bool cmp1(const int & a,const int & b)
  {
return (s[a]<s[b]);
}
bool cmp2(const int & a,const int & b)
  {
return (rank[a]<rank[b] || (rank[a]==rank[b]&&
(a+k<n?rank[a+k]:-1)<(b+k<n?rank[b+k]:-1)));
}
void suffixArray()
  {
int i,j;
for(i=0;i<n;i++)
sa[i]=i;
sort(sa,sa+n,cmp1);
for(i=0;i<n;i++)
 {
if(i==0||s[sa[i]]!=s[sa[i-1]])
rank[sa[i]]=i;
else rank[sa[i]]=rank[sa[i-1]];
}
for(k=1;k<n;k*=2)
 {
sort(sa,sa+n,cmp2);
for(i=0;i<n;i++)
 {
if( i==0 || (cmp2(sa[i],sa[i-1])||cmp2(sa[i-1],sa[i])) )
h[sa[i]]=i;
else h[sa[i]]=h[sa[i-1]];
}
memcpy(rank, h, n * sizeof(int));
}

height[0] = 0;
for(i = 0, j = 0; i < n; i++)
 {
if(rank[i]>0)
 {
while(s[sa[rank[i] - 1] + j] == s[i + j])
j++;
height[rank[i]] = j;
if(j > 0) j--;
}
}
}
void rmq_init()
  {
int p=rank[0];
int i,smin;
h[0]=n;
smin=INT_MAX;
for(i=p;i>0;i--)
 {
if(height[i]<smin)
smin=height[i];
h[sa[i-1]]=smin; //这里放到数组h里面只是复用,以节省空间
}
smin=INT_MAX;
for(i=p+1;i<n;i++)
 {
if(height[i]<smin)
smin=height[i];
h[sa[i]]=smin;
}
}
int main()
  {
int t,p,x;
scanf("%d", &t);
while(t--)
 {
scanf("%s",s);
strrev(s);
n = strlen(s);
s[n]='$';
suffixArray();
rmq_init();
scanf("%d",&p);
while(p--)
 {
scanf("%d",&x);
printf("%d\n",h[n-x]);
}
}
return 0;
}
|