HDU 5030 Rabbit ' s String suffix array two-part construction

Source: Internet
Author: User
Tags character set min

Test instructions: Given a string, you divide him into K-strings at most, pick out the largest substring of the dictionary in each substring, and pick out the most dictionary-ordered string from all the selected strings. Now hopefully, the last string to pick out is small enough.

Idea: The last string to pick out is also a substring of the original string. At the same time, the larger the dictionary sequence, the more likely the string is to become the final result. So satisfying monotonicity, we can use the dichotomy method to solve.

First, the suffix array is used to get all the different substrings. Then, the direct two-point answer, determine whether the substring can be constructed to meet the test instructions.

How to construct it.

First, understand that our two-point answer is the largest substring in all substrings. Any substring of the other string cannot be greater than his in the dictionary order.

In this way, we can find out, for the substring starting with I, where to end, can make this substring greater than the two-point answer.

For this answer, in the SA array, all of the preceding substrings are smaller than him, and that end position must be at the end of the entire string.

In the SA array, the string at the back of the answer, if there is no public prefix, you can find a larger one than the answer, regardless of the decomposition. This will not meet the above conditions.

But there's a public prefix. At this time, we are going to construct it from the front to the back. If such a substring is less than k, then we can not allow these substrings to be formed by proper partitioning. If such a substring is greater than k, then no matter how it is split, there will be at least one such substring, in which case the answer is wrong.

Note: The key to this topic is if you construct such a string. Since the suffix array is the embodiment of the suffix, we can recursively construct the string from the go-back.

At the same time, the suffix array is sorted for all the substrings, and the dichotomy method can be used to solve some problems of satisfying monotonicity.

The code is as follows:

#include <cstring> #include <cstdio> #include <algorithm> using namespace std;

const int MAX = 100010;
int k,n;
Char Str[max];
int R[max];
Long Long Sum[max];

    int Limit[max];
    const int MAXN = 1000100;
    int RK[MAXN],SA[MAXN],HEIGHT[MAXN];
    int a[maxn],b[maxn],cnt[200000];
    The string to be sorted is R, length n, Range r[0]-r[n-1], and the value range is 0-n-1.

    Character set is m, range 1-m;
        void Radix_sort (int * r, int *a, int *b, int n, int m) {//A radix is sorted by R, stored to B, n in length, and the character set is M-memset (cnt,0,sizeof (CNT));
        for (int i = 0; i < n; ++i) ++cnt[r[a[i]];
        for (int i = 1; I <= m; ++i) cnt[i] + = cnt[i-1];
    for (int i = n-1; I >= 0; i) b[--cnt[r[a[i]]] [= A[i];
        } void Calc_sa (int*r, int n, int m) {for (int i = 0; i < n; ++i) rk[i] =i;

        Radix_sort (R,RK,SA,N,M);
        Rk[sa[0]] = 0;
        for (int i = 1; i < n; ++i) rk[sa[i]]= Rk[sa[i-1]] + (r[sa[i]]!=r[sa[i-1]); for (int i = 0; 1<<i< N, ++i) {for (int j = 0; J < N;
                ++J) {A[j] = rk[j]+1; B[J] = j + (1<<i) >=n?
                0:rk[j + (1<<i)] + 1;
            SA[J] = j;
            } radix_sort (B,sa,rk,n,n);
            Radix_sort (A,rk,sa,n,n);
            Rk[sa[0]] = 0; for (int j = 1; j < n; ++j) {rk[sa[j]] = Rk[sa[j-1]] + (a[sa[j-1] [! = A[sa[j]] | | b[sa[j-1]]! = B[sa[j]
            );
        }}}} void Calc_height (int * r,int N) {//Calculate height for (int i = 0; i < n; ++i) rk[sa[i]] = i;
        int h = 0;
            for (int i = 0; i < n; ++i) {h = h = = 0?0:h-1;
            if (rk[i]!= 0) while (r[i + h] = = R[sa[rk[i]-1] + h]) h++;
        Height[rk[i]] = h;
    }} bool Judge (long long mid) {int pos = lower_bound (sum + 1, sum + 1 + n,mid)-sum-1;

    int len = Mid-sum[pos] + Height[pos];
    for (int i = 0; i < POS; ++i) limit[sa[i]] = n;
  Limit[sa[pos]] = Sa[pos] + len;  int mii = height[pos+1];
        for (int i = pos + 1; i < n; ++i) {mii = min (mii,height[i]);
    Limit[sa[i]] = sa[i] + min (mii,len);
    } int need = 1;
    Mii = n;
        for (int i = 0; i < n; ++i) {if (i = = Limit[i]) return false;
            if (i >= mii) {if (++need > K) return false;
        Mii = n;
    mii = min (mii,limit[i]);
} return true;
    } int main (void) {//freopen ("Input.txt", "R", stdin);
        while (scanf ("%d", &k), K) {scanf ("%s", str);
        n = 0;
        for (; str[n];n++) r[n] = Str[n];
        Calc_sa (r,n,256);
        Calc_height (R,n);
        Sum[0] = 0;
        for (int i = 1; I <= n; ++i) sum[i] = Sum[i-1] + n-sa[i-1]-height[i-1];
        Long long lb = 0,ub = Sum[n];
            while (lb + 1 < UB) {Long Long mid = (lb + ub) >> 1;
            if (judge (mid)) UB = mid;
        else lb = mid; } int pos = Lower_bound (sum+ 1, sum + 1 + n,ub)-sum-1;
        int len = Ub-sum[pos] + Height[pos];
        pos = Sa[pos];
        Str[pos + len] = 0;
    printf ("%s\n", str + pos);
} return 0;
 }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.