problem 2075 SubstringAccept:70 submit:236
Time limit:1000 mSec Memory limit:65536 KB problem Descriptiongiven A string, find a substring of it which the Origi NAL string contains exactly n such substrings. Inputthere is several cases. The first line of each case contains an integer n.the second line contains a string, no longer than 100000. Outputif the such substring doesn ' t exist, output "impossible", else output the substring that appeared n times in the Ori Ginal string. If There is multiple solutions, output lexicographic smallest substring. Sample Input2ababba Sample OUTPUTAC code
<pre name= "code" class= "CPP" >,
<pre name= "code" class= "CPP" > #include <stdio.h> #include <string.h> #include <algori thm> #include <iostream> #define MIN (A, b) (A>B?B:A) #define MAX (A, B) (A>B?A:B) using namespace Std; Char str[103030]; int sa[103030],rank[103030],rank2[103030],height[103030],c[103030],*x,*y; int n; void cmp (int n,int sz) {int i; Memset (C,0,sizeof (c)); for (i=0;i<n;i++) c[x[y[i]]]++; for (i=1;i<sz;i++) c[i]+=c[i-1]; for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; } void Build_sa (char *s,int n,int sz) {x=rank,y=rank2; int i,j; for (i=0;i<n;i++) x[i]=s[i],y[i]=i; CMP (N,SZ); int Len; for (len=1;len<n;len<<=1) {int yid=0; for (i=n-len;i<n;i++) {Y[yid++]=i; } for (i=0;i<n;i++) if (Sa[i]>=len) Y[yid++]=sa[i]-len; CMP (N,SZ); Swap (x, y); X[sa[0]]=yid=0; for (i=1;i<n;i++) {if (Y[SA[I-1]]==Y[SA[I]]&&SA[I-1]+LEN<N&&SA[I]+LEN&L T;n&&y[sa[i-1]+len]==y[sa[i]+len]) X[sa[i]]=yid; else X[sa[i]]=++yid; } sz=yid+1; if (sz>=n) break; } for (i=0;i<n;i++) rank[i]=x[i]; } void GetHeight (char *s,int n) {int k=0; for (int i=0;i<n;i++) {if (rank[i]==0) continue; K=max (0,k-1); int j=sa[rank[i]-1]; while (S[i+k]==s[j+k]) k++; Height[rank[i]]=k; }} int minv[103010][20],lg[103030]; void Init_lg () {int i; lg[1]=0; for (i=2;i<102020;i++) {lg[i]=lg[i>>1]+1; }} void Init_rmq (int n) {int i,j,k; for (i=1;i<=n;i++) {minv[i][0]=height[i]; } for (j=1;j<=lg[n];j++) {for (k=0;k+ (1<<j) -1<=n;k++) { Minv[k][j]=min (minv[k][j-1],minv[k+ (1<< (j-1))][j-1]); }}} int LCP (int l,int R) {L=rank[l]; R=RANK[R]; if (l>r) swap (L,R); l++; int k=lg[r-l+1]; return min (minv[l][k],minv[r-(1<<k) +1][k]); } void Solve (int n,int k) {int i,j;for (i=1;i<=n;i++) {if (i+k-1>n) Break;int T=LCP (sa[i],sa[i+k-1]); if (t>height [i]&& (i+k>n| | T+k<=n&&t>height[i+k]) {for (j=0;j<t;j++) {printf ("%c", Str[j+sa[i]]);} printf ("\ n"); return;}} printf ("impossible\n");} int main () {int N;while (scanf("%d", &n)!=eof) {scanf ("%s", str), int len=strlen (str); Build_sa (str,len+1,128); getheight (Str,len); Init_lg (); INIT_RMQ (len); solve (len,n);}}
SOURCEFOJ Prize Month race-March 2012
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
FOJ topic 2075 Substring (suffix array to find the smallest dictionary order substring with k times)