Hdu 5030 Rabbit's String (suffix array & Binary), hdu5030
Rabbit's StringTime Limit: 40000/20000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission (s): 288 Accepted Submission (s): 108
Problem DescriptionLong long ago, there lived a lot of rabbits in the forest. One day, the king of the rabbit kingdom got a mysterious string and he wanted to study this string.
At first, he wocould divide this string into no more than k substrings. then for each substring S, he looked at all substrings of S, and selected the one which has the largest dictionary order. among those substrings selected in the second round, the king then choose one which has the largest dictionary order, and name it as a "magic string ".
Now he wanted to figure out how to divide the string so that the dictionary order of that "magic string" is as small as possible.
InputThere are at most 36 test cases.
For each test case, the first line contains a integer k indicating the maximum number of substrings the king coshould divide, and the second line is the original mysterious string which consisted of only lower letters.
The length of the mysterious string is between 1 and 105 and k is between 1 and the length of the mysterious string, inclusive.
The input ends by k = 0.
OutputFor each test case, output the magic string.
Sample Input
3bbaa2ababa0
Sample Output
bbaHint For the first test case, the king may divide the string into "b", "b" and "aa". For the second test case, the king may divide the string into "aba" and "ba".
Source2014 ACM/ICPC Asia Regional Guangzhou Online
Recommendhujie | We have carefully selected several similar problems for you: 5053 5052 5051 5050 question: give you a string of no more than 1 E5. You can cut it into k consecutive substrings at most. Then, extract the largest lexicographically ordered substring (the substring) from the substring ). Then, the most important sub-string in the Lexicographic Order is called the magic string. Now you need to output the smallest magic string in the Lexicographic Order. Train of Thought: the largest and smallest. It is easy to think of binary (now conditioned reflection ). First, we can find sa and height. Then we can find out how many different substrings are in the suffix of f [I], that is, the top I. Then we rank two magic strings. Through ranking, we can use the f array to locate the ranking pos of the suffix of the magic string and the length len of the magic string. The solution is to determine whether the solution is feasible. If tp = lcp (pos, x) = 0 is a suffix with a ranking greater than pos, there is no solution. No matter how it is cut, it is useless. Otherwise we can switch a knife at [sa [x], sa [x] + TP-1. All suffixes after pos are marked once. And then greedy to cut. Check the minimum number of knives. Then you can determine. For details, see the code:
# Include <algorithm> # include <iostream> # include <string. h> # include <stdio. h> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 100010; typedef long ll; char txt [maxn]; int sa [maxn], T1 [maxn], t2 [maxn], ct [maxn], he [maxn], rk [maxn], n, m, cut; int mk [maxn]; ll f [maxn], ans; void getsa (char * st) {int I, k, p, * x = T1, * y = T2; for (I = 0; I <m; I ++) ct [I] = 0; for (I = 0; I <n; I ++) ct [x [I] = st [I] ++; for (I = 1; I <m; I ++) ct [I] + = ct [I-1]; for (I = n-1; I> = 0; I --) sa [-- ct [x [I] = I; for (k = 1, p = 1; p <n; k <= 1, m = p) {for (p = 0, I = n-k; I <n; I ++) y [p ++] = I; for (I = 0; I <n; I ++) if (sa [I]> = k) y [p ++] = sa [I]-k; for (I = 0; I <m; I ++) ct [I] = 0; for (I = 0; I <n; I ++) ct [x [y [I] ++; for (I = 1; I <m; I ++) ct [I] + = ct [I-1]; for (I = n-1; I> = 0; I --) sa [-- ct [x [y [I] = y [I]; for (swap (x, y), p = 1, x [sa [0] = 0, I = 1; I <n; I ++) x [sa [I] = y [sa [I-1] = y [sa [I] & y [sa [I-1] + k] = y [Sa [I] + k]? P-1: p ++ ;}} void gethe (char * st) {int I, j, k = 0; for (I = 0; I <n; I ++) rk [sa [I] = I; for (I = 0; I <n-1; I ++) {if (k) k --; j = sa [rk [I]-1]; while (st [I + k] = st [j + k]) k ++; he [rk [I] = k ;}} bool isok (ll p) {int pos, len, I, pp, cnt; pos = lower_bound (f + 1, f + 1 + n, p)-f; // locate sa len = he [pos] + p-f [pos-1]; // determine the string length for (I = 0; I <n; I ++) mk [I] =-1; if (n-sa [pos]> len) // check whether the suffix of your own to cut mk [sa [pos] = sa [pos] + len-1; for (I = pos + 1; I <= n; I ++) {if (he [I] = 0) retur N false; len = min (len, he [I]); // lcp mk [sa [I] = sa [I] + len-1; // sorting is bigger than pos and must be separated.} Pp = n, cnt = 0; for (I = 0; I <n; I ++) {if (mk [I]! =-1) // it is impossible to cut the image together with the backend. Greedy thoughts. Pp = min (pp, mk [I]); if (pp = I) {cnt ++; if (cnt> cut) return false; pp = n ;}} return cnt <cut; // The number of cnt switches is cnt + 1 .} Int main () {int I, pos, len; ll low, hi, mid; while (scanf ("% d", & cut), cut) {scanf ("% s", txt); n = strlen (txt) + 1; m = 128; getsa (txt); gethe (txt); n --; f [1] = n-sa [1]; for (I = 2; I <= n; I ++) f [I] = f [I-1] + n-sa [I]-he [I]; low = 1, hi = f [n], ans = 1; while (low <= hi) {mid = (low + hi)> 1; if (isok (mid) ans = mid, hi = mid-1; else low = mid + 1;} pos = lower_bound (f + 1, f + 1 + n, ans)-f; len = he [pos] + ans-f [pos-1]; txt [sa [pos] + len] = 0; printf ("% s \ n ", txt + sa [pos]);} return 0 ;}
ACM: when calling a function with a suffix array, why does the length parameter of a string need to be added?
For convenience, you can add a character after the string. This character has not appeared before and is smaller than the previous one. Generally, it is set to 0, so the length must be 1.
Who can tell me the suffix array in acm?
Hi.baidu.com/...6.html
In addition to the paper mentioned in the article, if you still don't understand it, you can't do it.