码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 2946

时间:2015-04-22 21:55:49      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

 

二分+后缀数组

在height数组上二分

 

技术分享
  1 /**************************************************************
  2     Problem: 2946
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:956 ms
  7     Memory:1596 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <vector>
 14 #define N 10010
 15 using namespace std;
 16  
 17 int tot;
 18 int n, aa[N];
 19 int sa[2][N], rk[2][N], ht[N], vv[N], p, q;
 20 int bel[N];
 21 bool mark[10]; 
 22  
 23 void expand( int k ) {
 24     for( int i=1; i<=n; i++ ) vv[rk[p][sa[p][i]]] = i;
 25     for( int i=n; i>=1; i-- ) 
 26         if( sa[p][i]>k ) 
 27             sa[q][vv[rk[p][sa[p][i]-k]]--]=sa[p][i]-k;
 28     for( int i=n-k+1; i<=n; i++ ) 
 29         sa[q][vv[rk[p][i]]--] = i;
 30     for( int i=1; i<=n; i++ )
 31         rk[q][sa[q][i]] = rk[q][sa[q][i-1]]+
 32             (rk[p][sa[q][i]]!=rk[p][sa[q][i-1]]||rk[p][sa[q][i]+k]!=rk[p][sa[q][i-1]+k]);
 33 }
 34 void calcht() {
 35     for( int i=1,k=0; i<=n; i++ ) {
 36         if( rk[p][i]==1 ) {
 37             k = ht[i] = 0;
 38             continue;
 39         }
 40         int j=sa[p][rk[p][i]-1];
 41         while( aa[i+k]==aa[j+k] ) k++;
 42         ht[i] = k;
 43         if( k>0 ) k--;
 44     }
 45 }
 46 void suffix() {
 47     p=1, q=0;
 48     for( int i=1; i<=n; i++ ) vv[aa[i]]++;
 49     for( int i=1; i<=27; i++ ) vv[i]+=vv[i-1];
 50     for( int i=n; i>=1; i-- ) sa[p][vv[aa[i]]--]=i;
 51     for( int i=1; i<=n; i++ ) 
 52         rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(aa[sa[p][i]]!=aa[sa[p][i-1]]);
 53     for( int k=1; k<n; k<<=1,swap(p,q) )
 54         expand(k);
 55     calcht();
 56 }
 57 bool ok( int k ) {
 58     int top=1;
 59     for( int i=2; i<=n; i++ ) {
 60         if( ht[sa[p][i]]<k ) {
 61             int cnt = 0;
 62             for( int j=0; j<=n; j++ )
 63                 mark[j] = false;
 64             for( int j=top; j<i; j++ ) {
 65                 int ps = sa[p][j];
 66                 if( bel[ps] && !mark[bel[ps]] ) {
 67                     cnt++;
 68                     mark[bel[ps]] = true;
 69                 }
 70             }
 71             if( cnt==tot ) return true;
 72             top = i;
 73         }
 74     }
 75     return false;
 76 }
 77 int sov() {
 78     int lf=0, rg=2000;
 79     while( lf<rg ) {
 80         int mid=(lf+rg+1)>>1;
 81         if( ok(mid) ) lf=mid;
 82         else rg=mid-1;
 83     }
 84     return lf;
 85 }
 86 void test() {
 87     const char buf[] = " abcba";
 88     n = 5;
 89     for( int i=1; i<=n; i++ )
 90         aa[i] = buf[i]-a+1;
 91     suffix();
 92     for( int i=1; i<=n; i++ )
 93         printf( "%d: %s\n", ht[sa[p][i]], buf+sa[p][i] );
 94 }
 95 int main() {
 96     static char buf[N];
 97     scanf( "%d", &tot );
 98     for( int i=1; i<=tot; i++ ) {
 99         scanf( "%s", buf );
100         for( int j=0; buf[j]; j++ ) {
101             n++;
102             aa[n] = buf[j]-a+1;
103             bel[n] = i;
104         }
105         if( i!=tot ) {
106             n++;
107             aa[n] = 27;
108             bel[n] = 0;
109         }
110     }
111     suffix();
112     printf( "%d\n", sov() );
113 }
View Code

 

bzoj 2946

标签:

原文地址:http://www.cnblogs.com/idy002/p/4448761.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!