zoukankan      html  css  js  c++  java
  • poj 1743

    题意:给出一个串,求两个不相交的长度相等的子串,使得对应位置的差相等。

    题解:首先,假设串是a[0],a[1],...a[n],先作差,即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[n]的两个不相交的公共子串。

    先将h数组求出来,然后二分子串长度,。。。。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #define maxn 20010
     5 using namespace std;
     6 
     7 int n;
     8 int aa[maxn], sa[maxn], rk[maxn], ht[maxn], vv[maxn];
     9 
    10 void expand( int k, int sa[maxn], int rk[maxn], int tsa[maxn], int trk[maxn] ) {
    11     for( int i=1; i<=n; i++ ) vv[rk[sa[i]]]=i;
    12     for( int i=n; i>=1; i-- ) if( sa[i]>k ) tsa[vv[rk[sa[i]-k]]--]=sa[i]-k;
    13     for( int i=n-k+1; i<=n; i++ ) tsa[vv[rk[i]]--]=i;
    14     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]);
    15 }
    16 void calcht() {
    17     int k=0;
    18     ht[sa[1]]=0;
    19     for( int i=1; i<=n; i++ ) {
    20         if( rk[i]==1 ) continue;
    21         int j=sa[rk[i]-1];
    22         while( aa[i+k]==aa[j+k] ) k++;
    23         ht[i] = k;
    24         if( k>0 ) k--;
    25     }
    26 }
    27 void suffix() {
    28     static int tsa[maxn], trk[maxn];
    29     for( int i=1; i<=180; i++ ) vv[i]=0;
    30     for( int i=1; i<=n; i++ ) vv[aa[i]]++;
    31     for( int i=1; i<=180; i++ ) vv[i]+=vv[i-1];
    32     for( int i=1; i<=n; i++ ) sa[vv[aa[i]]--]=i;
    33     for( int i=1; i<=n; i++ ) rk[sa[i]]=rk[sa[i-1]]+(aa[sa[i]]!=aa[sa[i-1]]);
    34     int *pa=sa, *pb=rk, *pc=tsa, *pd=trk;
    35     for( int k=1; k<n; k<<=1,swap(pa,pc),swap(pb,pd) )
    36         expand(k,pa,pb,pc,pd);
    37     if( pa!=sa ) memcpy( sa, tsa, sizeof(sa) ), memcpy( rk, trk, sizeof(rk) );
    38     calcht();
    39 }
    40 bool ok( int len ) {    //    len>=1
    41     int top, minp, maxp;
    42     top = minp = maxp = sa[1];
    43     for( int i=2; i<=n; i++ ) {
    44         if( ht[sa[i]]<len ) {
    45             if( maxp-minp>=len ) return true;
    46             top = minp = maxp = sa[i];
    47         } else {
    48             if( minp>sa[i] ) minp=sa[i];
    49             if( maxp<sa[i] ) maxp=sa[i];
    50         }
    51     }
    52     if( maxp-minp>=len ) return true;
    53     return false;
    54 }
    55 int main() {
    56     while( scanf("%d",&n)==1 ) {
    57         if( n==0 ) break;
    58         n--;
    59         for( int i=0; i<=n; i++ )
    60             scanf( "%d", aa+i );
    61         for( int i=n; i>=1; i-- )
    62             aa[i]=aa[i]-aa[i-1]+88;
    63         suffix();
    64         int lf=0, rg=n/2;
    65         while( lf<rg ) {
    66             int mid=(lf+rg+1)>>1;
    67             if( ok(mid) ) lf=mid;
    68             else rg=mid-1;
    69         }
    70         lf++;
    71         printf( "%d
    ", lf<5 ? 0 : lf  );
    72     }
    73 }
    View Code
  • 相关阅读:
    spring boot 1.4 整合 mybatis druid
    大话设计模式读书笔记--6个原则
    大话设计模式读书笔记--23.访问者模式
    大话设计模式读书笔记--22.解释器模式
    大话设计模式读书笔记--21.享元模式
    大话设计模式读书笔记--20.中介者模式
    大话设计模式读书笔记--19.责任链模式
    大话设计模式读书笔记--18.命令模式
    大话设计模式读书笔记--17.桥接模式
    大话设计模式读书笔记--17.单例模式
  • 原文地址:https://www.cnblogs.com/idy002/p/4345371.html
Copyright © 2011-2022 走看看