HDU 4898 LCP + greedy thinking

Source: Internet
Author: User

Cut a string into k blocks to minimize the largest block in the Lexicographic Order.

Orz wjmzbmr. It takes only one day to understand the problem.

You can use LCP (longest common prefix) to quickly compare the size of two substrings. It is enough to compare the size of the next character with the common prefix.

With this idea, we can first pre-process the LCP (suffix array + record O (2 nlog (2n) + O (N * n) of all substrings ), DP (O (4 * n )))

Then sort these substrings by lexicographically using LCP to start the second answer.

The second answer is the upper limit of the K block lexicographic orders. Assuming that I is used as the starting point, because the upper limit of the Lexicographic Order is known, we can immediately find the nearest vertex to be selected.

Now the problem is: knowing that each point can jump the r distance as far as possible, and finding whether there is a path, so that K hops return to the start point.

First, we assume that the R of each vertex is equal to 0, which means that each vertex can jump backward. In this way, we only need to use greedy ideas to enumerate any vertex as the starting point, the number of hops that can be jumped back. If the number of hops T <= K is returned, the value is true. Because each vertex can jump back, we can change several hops, so that t = K if the current number of points is less than K, that is, the number cannot be jumped to every step. Of course, it is false]

The problem is that if there are some points r = 0, that is, it cannot jump back, and other positions cannot jump to this position. Therefore, we thought that we would delete this vertex and subtract one from all affected vertices. We can skip three steps from, but now B (A <= B <= a + 3) is deleted, so a can only pick two steps, so after a can iterate n times at most, R of all vertices is not 0.

Code writing is frustrating...

#include <cstdio>#include <iostream>#include<algorithm>#include<cstring>#include<cmath>#include<queue>using namespace std;#define maxn 2005char str[maxn];int sa[maxn],t1[maxn],t2[maxn],c[maxn],n;void suffix(int m){    int *x=t1,*y=t2;    for(int i=0; i<m; i++)c[i]=0;    for(int i=0; i<n; i++)c[x[i]=str[i]]++;    for(int i=1; i<m; i++)c[i]+=c[i-1];    for(int i=n-1; i>=0; i--)sa[--c[x[i]]]=i;    for(int k=1; k<=n; k<<=1)    {        int p=0;        for(int i=n-k; i<n; i++)y[p++]=i;        for(int i=0; i<n; i++)if(sa[i]>=k)y[p++]=sa[i]-k;        for(int i=0; i<m; i++)c[i]=0;        for(int i=0; i<n; i++)c[x[y[i]]]++;        for(int i=0; i<m; i++)c[i]+=c[i-1];        for(int i=n-1; i>=0; i--)sa[--c[x[y[i]]]]=y[i];        swap(x,y);        p=1;        x[sa[0]]=0;        for(int 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++;        if(p>=n)break;        m=p;    }}int rank[maxn],height[maxn];void getheight(){    int k=0;    for(int i=0; i<n; i++)rank[sa[i]]=i;    for(int i=0; i<n; i++)    {        if(k)k--;        if(!rank[i])continue;        int j=sa[rank[i]-1];        while(str[i+k]==str[j+k])k++;        height[rank[i]]=k;    }}int f[maxn][30];void RMQINIT(){    for(int i=0;i<n;i++)    f[i][0]=height[i];    for(int j=1;(1<<j)<=n;j++)        for(int i=0;i+(1<<j)-1<n;i++)            f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);}int RMQ(int l,int r){    if(l>r)swap(l,r);    l++;    int k=floor(log(r-l+1.0)/log(2.0));    return min(f[l][k],f[r+1-(1<<k)][k]);}int tn,k,st,mid;int lcp(int l,int r){    if(l==r) return n-l;    return RMQ(rank[l],rank[r]);}int Lcp[1015][1015];struct node{    int l,r;    int size;    bool operator <(const node &x) const    {        int LCP=min(size,Lcp[l][x.l]);        LCP=min(LCP,x.size);        char a = LCP<size?str[l+LCP]:0;        char b = LCP<x.size?str[x.l+LCP]:0;        return a<b;    }}a[1111111];vector<int> v[maxn];void debug(int pos){    for(int i=a[pos].l;i<a[pos].r;i++)    {        putchar(str[i]);    }    puts("");}bool vis[maxn];vector<int>far;bool cal(){    far.clear();    for(int i=0;i<tn;i++)    {        if(i==a[mid].l)        {            far.push_back(a[mid].size);            continue;        }        int LCP=min(tn,Lcp[i][a[mid].l]);        LCP=min(LCP,a[mid].size);        if(LCP>=tn)        {            far.push_back(tn);            continue;        }        else        {            if(str[i+LCP]<str[a[mid].l+LCP]) far.push_back(tn);            else far.push_back(LCP);        }    }    int ok=1;    while(ok)    {        ok=0;        for(int i=0;i<far.size();i++)        {            if(far[i]==0)            {                for(int j=0;j<far.size();j++)                {                    if(j<i&&i<=j+far[j]) far[j]--;                    else if(j>i&&j+far[j]>=i+far.size()) far[j]--;                }                ok=1;                far.erase(i+far.begin());            }        }    }    if(far.size()<k) return false;    int len=far.size();    for(int i=0;i<len;i++) far.push_back(far[i]);    for(int i=0;i<len;i++)    {        int times=0;        for(int j=i;j<i+len;j+=far[j]) times++;        if(times<=k) return true;    }    return false;}int main(){    int cas;    scanf("%d",&cas);    while(cas--)    {        scanf("%d%d",&n,&k);        scanf("%s",str);        tn=n;        if(k==1) {puts(str);continue;}        for(int i=n;i<2*n;i++) str[i]=str[i-n];        n*=2;        str[n]=0;        n++;        suffix(128);        getheight();        RMQINIT();        n--;        int top=0;        for(int i=0;i<tn;i++)        {            for(int j=i;j<i+tn;j++)            {                a[++top].l=i;                a[top].r=j+1;                a[top].size=j+1-i;            }        }        for(int i=0;i<=tn;i++)            for(int j=0;j<=tn;j++)                Lcp[i][j]=lcp(i,j);        sort(a+1,a+top+1);        int l=1,r=top,ans;        while(l<=r)        {            mid=(l+r)/2;            if(cal())            {                ans=mid;                r=mid-1;            }            else            {                l=mid+1;            }        }        debug(ans);    }    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.