2014西安网络预选赛1002(后缀数组求第K大的子串)hdu5008

Boring String Problem

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 272    Accepted Submission(s): 65


Problem Description
In this problem, you are given a string s and q queries.

For each query, you should answer that when all distinct substrings of string s were sorted lexicographically, which one is the k-th smallest. 

A substring s i...j of the string s = a 1a 2 ...a n(1 ≤ i ≤ j ≤ n) is the string a ia i+1 ...a j. Two substrings s x...y and s z...w are cosidered to be distinct if s x...y ≠ S z...w
 

Input
The input consists of multiple test cases.Please process till EOF. 

Each test case begins with a line containing a string s(|s| ≤ 10 5) with only lowercase letters.

Next line contains a postive integer q(1 ≤ q ≤ 10 5), the number of questions.

q queries are given in the next q lines. Every line contains an integer v. You should calculate the k by k = (l⊕r⊕v)+1(l, r is the output of previous question, at the beginning of each case l = r = 0, 0 < k < 2 63, “⊕” denotes exclusive or)
 

Output
For each test case, output consists of q lines, the i-th line contains two integers l, r which is the answer to the i-th query. (The answer l,r satisfies that s l...r is the k-th smallest and if there are several l,r available, ouput l,r which with the smallest l. If there is no l,r satisfied, output “0 0”. Note that s 1...n is the whole string)
 

Sample Input
    
    
    
    
aaa 4 0 2 3 5
 

Sample Output
    
    
    
    
1 1 1 3 1 2 0 0

题意:找出第k大的子串,有多种情况要取l最小的一个

思路:比赛的时候看完题目以后大概知道是后缀数组,就没细想了,因为还有其它过的人更多的题没做出来= =

            首先注意后缀数组可以求出到第i个后缀一共有多少种不同的子串

            先不考虑前面的影响,而第i个后缀不同的子串的个数就等于在该后缀上找前缀的个数,就等于该后缀的长度,即cnt=n-sa[i]

            而这个cnt是包含了与上一个名次的后缀前面一样的串的个数,所以还要减去这部分(恰好等于height[i]),即cnt=cnt - height[i]

            然后对于查询,只需要二分找到第一个满足的sa[i],那么就可以从sa[i]开始往后枚举最小的下标,因为后面可能存在一样的串且下标更小

你可能感兴趣的:(ACM,HDU)