题意:求最长的可重叠的 K重复子串 的长度
考虑二分长度s,转化为验证性问题。
对SA进行分组。保证组内Height最小为s。这样在组内RMQ就可以任意了,因为RMQ一定是大于S的。
只要组内元素个数大于等于K就是可行解。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct SA{ 5 int str[1000005]; 6 int x[1000005],y[1000005],u[1000005],v[1000005],r[1000005],o[1000005],hei[1000005],m=1000005,n; 7 8 int a[5000005]; 9 10 void build(int p,int l,int r){ 11 if(l==r) a[p]=hei[l]; 12 else build(p*2,l,(l+r)/2), build(p*2+1,(l+r)/2+1,r), a[p]=min(a[p*2],a[p*2+1]); 13 } 14 15 int query(int p,int l,int r,int ql,int qr){ 16 if(l>qr||r<ql) return 1e+9; 17 if(l>=ql&&r<=qr) return a[p]; 18 return min(query(p*2,l,(l+r)/2,ql,qr),query(p*2+1,(l+r)/2+1,r,ql,qr)); 19 } 20 21 void calc(){ 22 int i,j,k=0; 23 //for(i=1; i<=n; i++) r[x[i]]=i; 24 for(i=1; i<=n; hei[r[i++]]=k) 25 for(k?k--:0,j=x[r[i]-1]; str[i+k]==str[j+k]; k++); 26 } 27 28 int solve(){ 29 //n=strlen(str+1); 30 //printf("len %d\n",n); 31 32 for(int i=1;i<=n;i++) u[str[i]]++; 33 for(int i=1;i<=m;i++) u[i]+=u[i-1]; 34 for(int i=n;i>=1;i--) x[u[str[i]]--]=i; 35 r[x[1]]=1; 36 for(int i=2;i<=n;i++) r[x[i]]=r[x[i-1]]+((str[x[i]]-str[x[i-1]])?1:0); 37 38 for(int l=1;r[x[n]]<n;l<<=1) { 39 memset(u,0,sizeof u); 40 memset(v,0,sizeof v); 41 memcpy(o,r,sizeof r); 42 for(int i=1;i<=n;i++) u[r[i]]++, v[(i+l<=n)?r[i+l]:0]++; 43 for(int i=1;i<=n;i++) u[i]+=u[i-1], v[i]+=v[i-1]; 44 for(int i=n;i>=1;i--) y[v[(i+l<=n)?r[i+l]:0]--]=i; 45 for(int i=n;i>=1;i--) x[u[r[y[i]]]--]=y[i]; 46 r[x[1]]=1; 47 for(int i=2;i<=n;i++) 48 r[x[i]]=r[x[i-1]]+((o[x[i]] != o[x[i-1]]) || (((x[i]+l<=n)?o[x[i]+l]:0) != ((x[i-1]+l<=n)?o[x[i-1]+l]:0))); 49 } 50 calc(); 51 hei[1]=0; 52 //build(1,1,n); 53 } 54 55 int lcp(int pos1,int pos2){ 56 return query(1,1,n,min(r[pos1],r[pos2])+1,max(r[pos1],r[pos2])); 57 } 58 59 } sa; 60 61 int n,k; 62 63 int main(){ 64 cin>>n>>k; 65 sa.n=n; 66 for(int i=1;i<=n;i++) cin>>sa.str[i]; 67 sa.solve(); 68 int l=1,r=1000000,ans=0; 69 while(r-l) { 70 int s=(l+r)/2,cnt=1,mx=0; 71 for(int i=1;i<=n+1;i++) 72 if(sa.hei[i]<s) 73 mx=max(cnt,mx), cnt=1; 74 else cnt++; 75 if(mx>=k) ans=max(ans,s), l=s+1; 76 else r=s; 77 } 78 cout<<ans<<endl; 79 80 81 82 }
原文地址:https://www.cnblogs.com/mollnn/p/8443097.html
时间: 2024-11-01 12:51:51