hihocoder #1419 : 后缀数组四·重复旋律4
http://hihocoder.com/problemset/problem/1419
这个题可以用类似https://www.cnblogs.com/hehe54321/p/8808226.html的方法A掉,分析比题解要简单...(应该吧?)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 typedef long long LL; 7 typedef unsigned long long ULL; 8 char s[100010]; 9 LL n,anss; 10 ULL powx[100100],hs[100100]; 11 const ULL X=131; 12 ULL ghash(LL x,LL y)//[x,y]的哈希 13 { 14 return hs[x]-hs[y+1]*powx[y-x+1]; 15 } 16 LL lcp(LL x,LL y)//后缀x和后缀y的lcp 17 { 18 if(x>n||y>n) return 0; 19 LL l=0,r=min(n-x+1,n-y+1)+1,mid; 20 while(r-l>1) 21 { 22 mid=l+(r-l)/2; 23 if(ghash(x,x+mid-1)==ghash(y,y+mid-1)) l=mid; 24 else r=mid; 25 } 26 return l; 27 } 28 LL lcs(LL x,LL y)//前缀x和前缀y的lcs 29 { 30 if(!x||!y) return 0; 31 LL l=0,r=min(x,y)+1,mid; 32 while(r-l>1) 33 { 34 mid=l+(r-l)/2; 35 if(ghash(x-mid+1,x)==ghash(y-mid+1,y)) l=mid; 36 else r=mid; 37 } 38 return l; 39 } 40 LL ans; 41 int main() 42 { 43 LL i,j,b,l,r,k; 44 scanf("%s",s+1);n=strlen(s+1); 45 powx[0]=1; 46 for(i=1;i<=100000;i++) powx[i]=powx[i-1]*X; 47 for(i=n;i>=1;i--) hs[i]=hs[i+1]*X+s[i]; 48 for(i=1;i<=n;i++) 49 { 50 b=n/i; 51 for(j=1,k=0;j<=b;j++) 52 { 53 for(;k<b&&ghash(i*(j-1)+1,i*j)==ghash(i*k+1,i*(k+1));k++); 54 //例如对于dba,bca,bca,bde 55 //当i=3,j=2时,k=3 56 l=min(i-1,lcs(i*(j-1),i*k));r=min(i-1,lcp(i*(j-1)+1,i*k+1)); 57 //此时l=1,r=1 58 ans=max(ans,k-j+1); 59 //此时只可能分成两段的倍数,且长度为k-j+1 60 //又例如:当i=3,j=3,k=3时 61 //l=2,r=1 62 //k-j+1=1,因此没有需要统计的 63 if(l+r>=i) ans=max(ans,k-j+2); 64 //但事实上有cabcab没有统计 65 //可以证明,像这种情况漏统计的串的循环次数最多比k-j+1大1 66 //漏统计的数量是从第i*(j-1)-l+1位开始的到第i*(j-1)+r-i+1位开始的 67 //共出现r+l-i+1次,每一次均循环k-j+2次 68 //显然只有当r+l-i+1大于0时才会有此情况 69 //又例如:例如ac,cc,c,当i=2,j=2,k=2,l=1,r=1时 70 //此时还有cccc被漏统计 71 //从第2位开始,到第2位结束,重复2次 72 } 73 } 74 printf("%lld",ans); 75 return 0; 76 }