bzoj3277&&bzoj3473 string (sa+ +LCP)

Source: Internet
Author: User
Tags stdin strlen time limit

First old routines, we put all the strings together, separated by separators, do SA, find H Array, and the St table for LCP. Then we analyze the topic and we count the answers separately for each string. Suppose we're doing the I-string, starting with the STA in the total string and ending with Ed. What we are asking for is each suffix a[sta...ed],a[sta+1...ed]...a[ed] contribution to the answer and. Suppose we are seeking A[j...ed] to contribute to this suffix. Then his contribution is that there are several prefixes appearing in the different strings of k and above, apparently if a[j. J+len-1] is satisfied and Len is the largest, the contribution to the answer is Len. We only need the biggest len. Considering that if A[j-1...ed] 's contribution to the answer is Len, then A[j...ed's contribution to the answer is at least len-1, and we can seek this contribution as we would for the H array. The
also needs to be implemented to determine whether A[j...j+len-1] (the following is a string T) appears in the different strings of k and above. First, according to the H array we can find the maximum interval [L. R] satisfies this r-l+1 suffix contains a string t. We count whether there are different strings of k or more in this interval. (See the simple procedure later)
optimization, you can find the interval of this [L...R] with two points. The
then is how to quickly determine whether there are different strings of k or more in this interval. We preprocess an L array, which indicates that there are different strings of k and above in the l[i]...i interval and l[i] max. (that is, to make the interval with the right endpoint of I satisfy the minimum interval of the condition) it is clear that this can be done over the O (n) scan. (Use a pointer p to indicate the movement of the left endpoint). You can quickly determine whether the [L...R] interval contains [L[R]...R] intervals. At this point, the problem is resolved. SA positive release

#include <cstdio> #include <cstring> #include <algorithm> #define LL Long long #define N 200010 int n=0,
m=30,nn,kk,a[n],len[n>>1],rank[n<<1],rank1[n],sa[n],h[n],tmp[n],count[n];
int st[n][20],log[n],tot=0,cnt[n>>1],l[n],bel[n];
Char s[n>>1];
    inline int min (int x,int y) {return x<y?x:y;} inline int LCP (int l,int R) {++l;
    int t=log[r-l+1];
return min (st[l][t],st[r-(1<<t) +1][t]); } bool Check (int x,int length) {//string sa[x]...sa[x]+length-1 whether to meet test instructions int xl,xr;//binary finds the largest [XL...XR] interval, which contains a string sa[x]...sa[x]+le
    Ngth-1 if (h[x]<length) xl=x;
        else{int l=1,r=x-1;
            while (l<=r) {int mid=l+r>>1;
        if (LCP (mid,x) >=length) R=mid-1;else l=mid+1;
    }xl=l;
    } if (h[x+1]<length) xr=x;
        else{int l=x+1,r=n;
            while (l<=r) {int mid=l+r>>1;
        if (LCP (X,mid) >=length) L=mid+1;else r=mid-1;
    }xr=r; } return l[xr]>=xl;//L[XR] to XR contains K and more different strings, see if XL...XR can contain} int main () {//Freopen ("A.in", "R", stdin);
    scanf ("%d%d", &AMP;NN,&AMP;KK);
        for (int i=1;i<=nn;++i) {scanf ("%s", s+1); Len[i]=strlen (s+1);
        for (int j=1;j<=len[i];++j) a[++n]=s[j]-' a ' +1,bel[n]=i;
    A[++n]=++m;
    }log[0]=-1;
    for (int i=1;i<=n;++i) log[i]=log[i>>1]+1;
    for (int i=1;i<=m;++i) count[i]=0;
    for (int i=1;i<=n;++i) count[a[i]]=1;
    for (int i=1;i<=m;++i) count[i]+=count[i-1];
    for (int i=n;i>=1;--i) rank[i]=count[a[i]];
    int k=0;
        for (int p=1;k!=n;p<<=1,m=k) {for (int i=1;i<=m;++i) count[i]=0;
        for (int i=1;i<=n;++i) count[rank[i+p]]++;
        for (int i=1;i<=m;++i) count[i]+=count[i-1];
        for (int i=n;i>=1;--i) tmp[count[rank[i+p]]--]=i;
        for (int i=1;i<=m;++i) count[i]=0;
        for (int i=1;i<=n;++i) count[rank[tmp[i]]]++;
        for (int i=1;i<=m;++i) count[i]+=count[i-1]; for (int i=n;i>=1;--i) Sa[count[ranK[tmp[i]]]--]=tmp[i];
        memcpy (rank1,rank,sizeof (RANK1));
        rank[sa[1]]=k=1; for (int i=2;i<=n;++i) {if (rank1[sa[i]]!=rank1[sa[i-1]]| |
            RANK1[SA[I]+P]!=RANK1[SA[I-1]+P]) ++k;
        Rank[sa[i]]=k;
    }}k=0;
        for (int i=1;i<=n;++i) {if (rank[i]==1) {h[1]=0;continue;} if (i==1| |
        H[rank[i-1]]<=1) k=0;
        if (k)--k;
        while (A[i+k]==a[sa[rank[i]-1]+k]) ++k;
    H[rank[i]]=k;
    } for (int i=1;i<=n;++i) st[i][0]=h[i]; for (int i=1;i<=log[n];++i) for (int j=1;j<=n;++j) if (j+ (1<<i-1) <=n) st[j][i]=min (st[j][i
    -1],st[j+ (1<<i-1)][i-1]);
        for (int i=1,p=1;i<=n;++i) {//by rank from small to large if (!bel[sa[i]]) break;
        if (cnt[bel[sa[i]]]==0) tot++;
        cnt[bel[sa[i]]]++; while (tot>kk| |
        TOT==KK&AMP;&AMP;CNT[BEL[SA[P]]]&GT;1) {//l[i] the right-most value P--cnt[bel[sa[p]]];if (cnt[bel[sa[p++]]]==0)--tot;
        } if (TOT&GT;=KK) l[i]=p; else l[I]=-1;
        } for (int i=1,sta=1;i<=nn;sta+=len[i++]+1) {ll ans=0;int k=0;
            for (int j=sta;j<=sta+len[i]-1;++j) {//statistic the contribution of each suffix of the I-string to the answer if (k)--k;
            while (J+k+1-1<=sta+len[i]-1&&check (rank[j],k+1)) ++k;
        Ans+=k;
    } printf ("%lld", ans); if (I!=NN) printf ("");
} return 0; }

Without two points of complexity is metaphysics, very easily will be data card ... But the 3473 data is really weak ... The violent run 368ms, is the solution to run 1400ms, also gave the 20s time limit ... The
Counter-view 3277 data is very reliable, violent tle ... And the positive solution ran 2496ms. (After all, I'm going to solve Sam ... Cover face) violent version

#include <cstdio> #include <cstring> #include <algorithm> #define LL Long long #define N 200010 int n=0,
m=30,nn,kk,a[n],len[n>>1],rank[n<<1],rank1[n],sa[n],h[n],tmp[n],count[n];
int st[n][20],log[n],tot=0,cnt[n>>1],l[n],bel[n];
Char s[n>>1]; inline int min (int x,int y) {return x<y?x:y;} bool Check (int x,int length) {//String sa[x]...sa[x]+length-1 whether test instructions int l=x is satisfied,
    r=x+1;
    while (h[l]>=length)--l;
    while (h[r]>=length) ++r;--r;
    Return l[r]>=l;//L[XR] to XR contains K and more different strings, see if XL...XR can contain} int main () {//Freopen ("A.in", "R", stdin);
    scanf ("%d%d", &AMP;NN,&AMP;KK);
        for (int i=1;i<=nn;++i) {scanf ("%s", s+1); Len[i]=strlen (s+1);
        for (int j=1;j<=len[i];++j) a[++n]=s[j]-' a ' +1,bel[n]=i;
    A[++n]=++m;
    }log[0]=-1;
    for (int i=1;i<=n;++i) log[i]=log[i>>1]+1;
    for (int i=1;i<=m;++i) count[i]=0;
    for (int i=1;i<=n;++i) count[a[i]]=1;
    for (int i=1;i<=m;++i) count[i]+=count[i-1]; for (int i=n;i>=1;--i) Rank[i]=count[a[i];
    int k=0;
        for (int p=1;k!=n;p<<=1,m=k) {for (int i=1;i<=m;++i) count[i]=0;
        for (int i=1;i<=n;++i) count[rank[i+p]]++;
        for (int i=1;i<=m;++i) count[i]+=count[i-1];
        for (int i=n;i>=1;--i) tmp[count[rank[i+p]]--]=i;
        for (int i=1;i<=m;++i) count[i]=0;
        for (int i=1;i<=n;++i) count[rank[tmp[i]]]++;
        for (int i=1;i<=m;++i) count[i]+=count[i-1];
        for (int i=n;i>=1;--i) sa[count[rank[tmp[i]]]--]=tmp[i];
        memcpy (rank1,rank,sizeof (RANK1));
        rank[sa[1]]=k=1; for (int i=2;i<=n;++i) {if (rank1[sa[i]]!=rank1[sa[i-1]]| |
            RANK1[SA[I]+P]!=RANK1[SA[I-1]+P]) ++k;
        Rank[sa[i]]=k;
    }}k=0;
        for (int i=1;i<=n;++i) {if (rank[i]==1) {h[1]=0;continue;} if (i==1| |
        H[rank[i-1]]<=1) k=0;
        if (k)--k;
        while (A[i+k]==a[sa[rank[i]-1]+k]) ++k;
    H[rank[i]]=k; } for (int i=1,p=1;i<=n;++i) {//by rank from small to large if (!bel[sa[i]]) break;
        if (cnt[bel[sa[i]]]==0) tot++;
        cnt[bel[sa[i]]]++; while (tot>kk| |
        TOT==KK&AMP;&AMP;CNT[BEL[SA[P]]]&GT;1) {//l[i] the right-most value P--cnt[bel[sa[p]]];if (cnt[bel[sa[p++]]]==0)--tot;
        } if (TOT&GT;=KK) l[i]=p;
    else L[i]=-1;
        } for (int i=1,sta=1;i<=nn;sta+=len[i++]+1) {ll ans=0;int k=0;
            for (int j=sta;j<=sta+len[i]-1;++j) {//statistic the contribution of each suffix of the I-string to the answer if (k)--k;
            while (J+k+1-1<=sta+len[i]-1&&check (rank[j],k+1)) ++k;
        Ans+=k;
    } printf ("%lld", ans); if (I!=NN) printf ("");
} 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.