zoukankan      html  css  js  c++  java
  • bzoj 2946

    二分+后缀数组

    在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
    ", 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
    ", sov() );
    113 }
    View Code
  • 相关阅读:
    Kafka
    js操作json
    Javascript的console.log()用法
    js中的instanceof运算符
    JS阻止事件冒泡的3种方法之间的不同
    js string to date
    JavaScript RegExp.$1
    JS正则表达式大全
    js data日期初始化的5种方法
    javascript和jquey的自定义事件小结
  • 原文地址:https://www.cnblogs.com/idy002/p/4448761.html
Copyright © 2011-2022 走看看