zoukankan      html  css  js  c++  java
  • pku 3261

    啊,好 郁闷,这应该就是不理解模板的带来的后果吧,用之前那个模板,写了好几遍,改了好几遍,一直wa,可是换一个模板就过了,之后还是用这个模板吧

    题意倒是很简单,就是求出至少重复k次的最长子串

    还是用二分的思想,找出一组后缀数目大于等于k的最大后缀即可

    #include <stdio.h>   
    #include <stdlib.h>   
    #include <string.h>   
    int const N= 20100;   
    int wa[N], wb[N], ws[N*2], wv[N];   
    int rank[N], sa[N], height[N], r[N], n, k,m;   
      
    int cmp( int* r, int a, int b, int L ){   
        return r[a]== r[b] && r[a+ L]== r[b+ L];   
    }   
      
    void da( int* r, int* sa, int n, int m ){   
        int i, j, p, *x= wa, *y= wb, *t;   
        for( i= 0; i< m; ++i ) ws[i]= 0;   
        for( i= 0; i< n; ++i ) ws[ x[i]= r[i] ]++;   
        for( i= 1; i< m; ++i ) ws[i]+= ws[i-1];   
        for( i= n- 1; i>= 0; i-- ) sa[ --ws[ x[i] ] ]= i;   
      
        for( j= 1, p= 1; p< n; j*= 2, m= p ){   
            for( p= 0, i= n- j; i< n; ++i ) y[p++]= i;   
            for( i= 0; i< n; ++i )   
                if( sa[i]>= j ) y[p++]= sa[i]- j;   
      
            for( i= 0; i< n; ++i ) wv[i]= x[y[i]];   
            for( i= 0; i< m; ++i ) ws[i]= 0;   
            for( i= 0; i< n; ++i ) ws[ wv[i] ]++;   
            for( i= 1; i< m; ++i ) ws[i]+= ws[i-1];   
            for( i= n- 1; i>= 0; i-- ) sa[ --ws[ wv[i] ] ]= y[i];   
      
            t= x, x= y, y= t, p= 1; x[ sa[0] ]= 0;   
            for( i= 1; i< n; ++i )   
                x[ sa[i] ]= cmp( y, sa[i-1], sa[i], j )? p- 1: p++;   
        }   
    }   
      
    void callheight( int* r, int*sa, int n ){   
        int i, j, k= 0;   
        for( i= 1; i<= n; ++i ) rank[ sa[i] ]= i;   
      
        for( i= 0; i< n; height[ rank[i++] ]= k )   
            for( k?k--:0, j= sa[ rank[i]- 1]; r[i+k]== r[j+k]; k++ );   
      
    }   
      
    int Check( int mid ){   
        int ans= 1;   
        for( int i= 1; i<= n; ++i ){   
            if( height[i]< mid ) ans= 1;   
            else ans++;   
      
            if( ans>= k ) return 1;   
        }   
        return 0;   
    }   
      
    int main(){   
        scanf("%d%d",&n,&k );  m=0; 
        for( int i= 0; i< n; ++i ){   
            scanf("%d", r+ i ); r[i]++; 
    		if(r[i]>m) m=r[i];
        }   
        r[n]= 0;   
        da( r, sa, n+ 1, ++m );   
        callheight( r, sa, n );   
      
        int left= 1, right= n;   
        while( left<= right ){   
            int mid= (left+ right)>>1;   
      
            if( Check( mid ) ) left= mid+ 1;   
            else right= mid- 1;   
        }   
        printf("%d\n", right );   
      
        return 0;   
    } 
    
  • 相关阅读:
    作为管理者的基本职责
    websocket接口自动化的封装
    locust性能测试的使用
    git的协作提交流程
    关于接口自动化的实施步骤
    K8S的组件梳理
    jenkins pipeline中,失败后获取异常不中断业务
    pipline在执行的docker镜像中添加hosts
    sonar搭建
    django
  • 原文地址:https://www.cnblogs.com/nanke/p/2050519.html
Copyright © 2011-2022 走看看