Test instructions
Give a string, at most, divide it into n parts, each of which takes out the maximum substring ci of the dictionary, minimizing the largest CI
Let's look at a simplified version of the question:
Given a string s, and then a substring of s t, ask whether it is possible to divide the string into K-parts so that T becomes the dictionary-ordered maximum substring of the divided s
for this problem, starting with the last face of the string s, a character forward pushing a characterif the current [L,r] dictionary order is larger than T, then [L+1,r] will be a separateCompare substring dictionary order size with two points + hashbecause we are a character that is pushed forward by a character, it must be the new L so that the current [L,r] dictionary order is larger than Tso if l==r at this point, then this t can't be the dictionary order maximum substringif the last part counts <=k, then this t canthen the only two-molecule string t is needed.so now the question becomes how to get a substring of the dictionary ordinal rank kThis can be obtained by the height of the suffix array[Sa[1],sa[1]] is the 1th small dictionary order[Sa[1],sa[1]+1] is the 2nd small dictionary order...[Sa[1],n] is the dictionary preface n-sa[1]+1 Small[Sa[2],sa[2]+height[2]] is the nextand the next one is [sa[2],sa[2]+height[2]+1]...
#include <cstdio>#include<cstring>#include<algorithm>using namespacestd;#defineN 100001typedefLong LongLL;Const int Base=13331;intn,m;CharS[n];intA[n];intV[n];intp,q=1, K;intsa[2][n],rk[2][n];inth[n];unsignedLong LongPow[n],has[n];p air<int,int>Interval[n];voidMulint*sa,int*rk,int*sa,int*RK) { for(intI=1; i<=n;++i) v[rk[sa[i]]]=i; for(intI=n;i;--i)if(sa[i]>k) sa[v[rk[sa[i]-k]]--]=sa[i]-K; for(inti=n-k+1; i<=n;++i) sa[v[rk[i]]--]=i; for(intI=1; i<=n;++i) rk[sa[i]]=rk[sa[i-1]]+ (rk[sa[i]]!=rk[sa[i-1]] || rk[sa[i]+k]!=rk[sa[i-1]+K]);}voidPresa () { for(intI=1; i<=n;++i) v[a[i]]++; for(intI=1; i<= -; ++i) v[i]+=v[i-1]; for(intI=1; i<=n;++i) sa[p][v[a[i]]--]=i; for(intI=1; i<=n;++i) rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+ (a[sa[p][i]]!=a[sa[p][i-1]]); for(k=1; k<n;k<<=1, Swap (P,Q)) Mul (Sa[p],rk[p],sa[q],rk[q]);}voidget_height () {intj,k=0; for(intI=1; i<=n;++i) {j=sa[p][rk[p][i]-1]; while(A[i+k]==a[j+k]) k++; H[rk[p][i]]=K; if(k) k--; }}voidPrehash () {pow[0]=1; for(intI=1; i<=n;++i) pow[i]=pow[i-1]*Base; for(intI=1; i<=n;++i) has[i]=has[i-1]*Base+a[i];} Pair<int,int>Select(LL k) {intNow ; LL sum=0; intL,r; for(intI=1; i<=n;++i) { now=interval[i].second-interval[i].first+1; if(sum+now>=k) {L=Sa[p][i]; R=interval[i].first+k-sum-1; returnMake_pair (L,R); } Sum+=Now ; }}unsignedLong LongGet_hash (intLintR) { returnhas[r]-has[l-1]*pow[r-l+1];}intCMP (pair<int,int>x,pair<int,int>y) { if(Get_hash (X.first,x.second) ==get_hash (Y.first,y.second))return 0; intlx=x.second-x.first+1, ly=y.second-y.first+1; intL=1, R=min (lx,ly), mid,tmp=0; while(l<=r) {Mid=l+r>>1; if(Get_hash (x.first,x.first+mid-1) ==get_hash (y.first,y.first+mid-1)) tmp=mid,l=mid+1; Elser=mid-1; } if(Tmp<min (lx,ly))returnS[X.FIRST+TMP]<S[Y.FIRST+TMP]? -1:1; returnLx<ly? -1:1;}BOOLCheck (pair<int,int>Now ) { intl=n,r=n,sum=1; while(l>=1) if(CMP (Make_pair (L,R), now) = =1) { if(L==R)return false; R=l; Sum++; if(sum>m)return false; } Elsel--; return true;}voidsolve () {LL L=1, r=0; for(intI=1; i<=n;++i) {Interval[i].first=sa[p][i]+H[i]; Interval[i].second=N; R+=interval[i].second-interval[i].first+1; } LL mid,tmp; Pair<int,int>Now ; while(l<=r) {Mid=l+r>>1; now=Select(mid); ifCheck (now) tmp=mid,r=mid-1; ElseL=mid+1; } Now=Select(TMP); L=now.first; R=Now.second; for(inti=l;i<=r;++i) Putchar (S[i]);} intMain () {Freopen ("string.in","R", stdin); Freopen ("String.out","W", stdout); scanf ("%d",&m); scanf ("%s", s+1); N=strlen (s+1); for(intI=1; i<=n;++i) a[i]=s[i]-'a'+1; Presa (); Get_height (); Prehash (); Solve ();}
2016vijos 1-1 rabbit string (suffix array + binary + hash)