poj 1743
2015-03-17 19:34
113 查看
题意:给出一个串,求两个不相交的长度相等的子串,使得对应位置的差相等。
题解:首先,假设串是a[0],a[1],...a
,先作差,即a[1]=a[1]-a[0],a[2]=a[2]-a[1],a[i]=a[i]-a[i-1],然后我们求a[1],a[2],a[3],...a
的两个不相交的公共子串。
先将h数组求出来,然后二分子串长度,。。。。
View Code
题解:首先,假设串是a[0],a[1],...a
,先作差,即a[1]=a[1]-a[0],a[2]=a[2]-a[1],a[i]=a[i]-a[i-1],然后我们求a[1],a[2],a[3],...a
的两个不相交的公共子串。
先将h数组求出来,然后二分子串长度,。。。。
#include <cstdio> #include <cstring> #include <iostream> #define maxn 20010 using namespace std; int n; int aa[maxn], sa[maxn], rk[maxn], ht[maxn], vv[maxn]; void expand( int k, int sa[maxn], int rk[maxn], int tsa[maxn], int trk[maxn] ) { for( int i=1; i<=n; i++ ) vv[rk[sa[i]]]=i; for( int i=n; i>=1; i-- ) if( sa[i]>k ) tsa[vv[rk[sa[i]-k]]--]=sa[i]-k; for( int i=n-k+1; i<=n; i++ ) tsa[vv[rk[i]]--]=i; for( int i=1; i<=n; i++ ) trk[tsa[i]]=trk[tsa[i-1]]+(rk[tsa[i]]!=rk[tsa[i-1]]||rk[tsa[i]+k]!=rk[tsa[i-1]+k]); } void calcht() { int k=0; ht[sa[1]]=0; for( int i=1; i<=n; i++ ) { if( rk[i]==1 ) continue; int j=sa[rk[i]-1]; while( aa[i+k]==aa[j+k] ) k++; ht[i] = k; if( k>0 ) k--; } } void suffix() { static int tsa[maxn], trk[maxn]; for( int i=1; i<=180; i++ ) vv[i]=0; for( int i=1; i<=n; i++ ) vv[aa[i]]++; for( int i=1; i<=180; i++ ) vv[i]+=vv[i-1]; for( int i=1; i<=n; i++ ) sa[vv[aa[i]]--]=i; for( int i=1; i<=n; i++ ) rk[sa[i]]=rk[sa[i-1]]+(aa[sa[i]]!=aa[sa[i-1]]); int *pa=sa, *pb=rk, *pc=tsa, *pd=trk; for( int k=1; k<n; k<<=1,swap(pa,pc),swap(pb,pd) ) expand(k,pa,pb,pc,pd); if( pa!=sa ) memcpy( sa, tsa, sizeof(sa) ), memcpy( rk, trk, sizeof(rk) ); calcht(); } bool ok( int len ) { // len>=1 int top, minp, maxp; top = minp = maxp = sa[1]; for( int i=2; i<=n; i++ ) { if( ht[sa[i]]<len ) { if( maxp-minp>=len ) return true; top = minp = maxp = sa[i]; } else { if( minp>sa[i] ) minp=sa[i]; if( maxp<sa[i] ) maxp=sa[i]; } } if( maxp-minp>=len ) return true; return false; } int main() { while( scanf("%d",&n)==1 ) { if( n==0 ) break; n--; for( int i=0; i<=n; i++ ) scanf( "%d", aa+i ); for( int i=n; i>=1; i-- ) aa[i]=aa[i]-aa[i-1]+88; suffix(); int lf=0, rg=n/2; while( lf<rg ) { int mid=(lf+rg+1)>>1; if( ok(mid) ) lf=mid; else rg=mid-1; } lf++; printf( "%d\n", lf<5 ? 0 : lf ); } }
View Code
相关文章推荐
- POJ1743(后缀数组)
- poj 1743 Musical Theme 后缀数组
- POJ 1743 Musical Theme 后缀数组+二分
- POJ 1743 后缀数组
- 【POJ】1743 Musical Theme
- POJ 1743 Musical Theme
- poj 1743 Musical Theme
- POJ 1743 Musical Theme(不可重叠最长重复子串 后缀数组)
- POJ 1743 Musical Theme
- A - Musical Theme POJ - 1743(后缀数组)
- POJ1743-Musical Theme
- POJ 1743 Musical Theme ——后缀数组
- poj 1743 Musical Theme 后缀数组
- POJ 1743 Musical Theme
- POJ 1743 Musical Theme(后缀数组)
- poj 1743后缀数组入门
- 后缀数组 Poj---1743 : Musical Theme
- POJ 1743 Musical Theme (后缀数组,求最长不重叠重复子串)
- POJ1743 Musical Theme
- [后缀自动机] POJ 1743 Musical Theme