zoukankan      html  css  js  c++  java
  • bzoj 3261

    题意:给定一个串,和一个数c,求一个长度最大的公共子串(可以重叠),并且该公共子串出现次数大于c。

    题解见罗穗骞论文。

    收获:

      计算高度函数时,遇到rk[i]==1的点时,要将k设置成0。(k是"h[i-1]-1")。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #define maxa 2000001
     5 #define maxn 20010
     6 using namespace std;
     7 
     8 int n, c;
     9 int aa[maxn], vv[maxa], sa[maxn], rk[maxn], ht[maxn];
    10 
    11 void expand( int k, int sa[maxn], int rk[maxn], int tsa[maxn], int trk[maxn] ) {
    12     for( int i=1; i<=n; i++ ) vv[rk[sa[i]]]=i;
    13     for( int i=n; i>=1; i-- ) if( sa[i]>k ) tsa[vv[rk[sa[i]-k]]--]=sa[i]-k;
    14     for( int i=n-k+1; i<=n; i++ ) tsa[vv[rk[i]]--]=i;
    15     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]);
    16 }
    17 void calcht() {
    18     for( int i=1,k=0; i<=n; i++ ) {
    19         if( rk[i]==1 ) {
    20             ht[i] = k = 0;
    21             continue;
    22         } 
    23         int j=sa[rk[i]-1];
    24         while( aa[i+k]==aa[j+k] ) k++;
    25         ht[i]=k;
    26         if(k>0)k--;
    27     }
    28 }
    29 void suffix() {
    30     static int vsa[maxn], vrk[maxn];
    31     for( int i=1; i<=n; i++ ) vv[aa[i]]++;
    32     for( int i=1; i<=maxa; i++ ) vv[i]+=vv[i-1];
    33     for( int i=1; i<=n; i++ ) sa[vv[aa[i]]--]=i;
    34     for( int i=1; i<=n; i++ ) rk[sa[i]]=rk[sa[i-1]]+(aa[sa[i]]!=aa[sa[i-1]]);
    35     int *a=sa, *b=rk, *c=vsa, *d=vrk;
    36     for( int k=1; k<n; k<<=1,swap(a,c),swap(b,d) ) expand(k,a,b,c,d);
    37     for( int i=1; i<=n; i++ ) sa[i]=a[i],rk[i]=b[i];
    38     calcht();
    39 }
    40 bool ok( int len ) {
    41     int top=1;
    42     for( int i=2; i<=n; i++ ) 
    43         if( ht[sa[i]]<len ) {
    44             if( i-top>=c ) {
    45                 return true;
    46             }
    47             top = i;
    48         } 
    49     if( n+1-top>=c ) return true;
    50     return false;
    51 }
    52 int main() {
    53     scanf( "%d%d", &n, &c );
    54     for( int i=1; i<=n; i++ ) {
    55         scanf( "%d", aa+i );
    56         aa[i]++;
    57     }
    58     aa[n+1] = -1;
    59     suffix();
    60     /*
    61     for( int i=1; i<=n; i++ ) {
    62         fprintf( stderr, "%d(%d): ", i, ht[sa[i]] );
    63         for( int j=sa[i]; j<=n; j++ )
    64             fprintf( stderr, "%d ", aa[j] );
    65         fprintf( stderr, "
    " );
    66     }
    67     */
    68     int lf=0, rg=n-c+1;
    69     while(lf<rg) {
    70         int mid=(lf+rg+1)>>1;
    71         if( ok(mid) ) lf=mid;
    72         else rg=mid-1;
    73     }
    74     printf( "%d
    ", lf );
    75 }
    View Code
  • 相关阅读:
    selenium-Selense、脚本语法
    selenium常用命令
    百度自动化测试脚本制作
    day2
    day1
    Python核心编程3-正则表达式
    redis
    mysql与系统优化
    mysql之mha高可用及读写分离
    作业一
  • 原文地址:https://www.cnblogs.com/idy002/p/4345520.html
Copyright © 2011-2022 走看看