zoukankan      html  css  js  c++  java
  • [USACO06DEC]牛奶模式Milk Patterns

    题目大意:

    给你一个串,问至少出现k次的子串的长度最大是多少。

    解题思路:

    这个子串的长度必然是原串k个不同后缀的LCP。

    建后缀数组,求出height。

    然后二分答案,每次在height里扫一遍即可。

    C++ Code:

    #include<bits/stdc++.h>
    using namespace std;
    int n,k,t1[20002],t2[20002],c[1000002],sa[20002],s[20002],rk[20002],height[20002];
    inline int min(int a,int b){return a<b?a:b;}
    inline void sa_sort(){
        int*x=t1,*y=t2,m=1000000;
        memset(c,0,sizeof c);
        for(int i=1;i<=n;++i)++c[x[i]=s[i]];
        for(int i=1;i<=m;++i)c[i]+=c[i-1];
        for(int i=n;i;--i)sa[c[x[i]]--]=i;
        for(int k=1;k<=n;k<<=1){
            int p=0;
            for(int i=n-k+1;i<=n;++i)y[++p]=i;
            for(int i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k;
            for(int i=0;i<=m;++i)c[i]=0;
            for(int i=1;i<=n;++i)++c[x[y[i]]];
            for(int i=1;i<=m;++i)c[i]+=c[i-1];
            for(int i=n;i;--i)sa[c[x[y[i]]]--]=y[i];
            int*tmp=x;x=y,y=tmp;
            x[sa[p=1]]=1;
            for(int i=2;i<=n;++i)
            x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p;
            if(p==n)break;
            m=p;
        }
    }
    inline void get_height(){
        for(int i=1;i<=n;++i)rk[sa[i]]=i;
        for(int i=1,k=0;i<=n;++i){
            if(rk[i]==1)continue;
            if(k)--k;
            int j=sa[rk[i]-1];
            while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k])++k;
            height[rk[i]]=k;
        }
    }
    bool check(int x){
        int nw=1,len=1<<30;
        for(int i=2;i<=n;++i){
            int mn=min(len,height[i]);
            if(mn>=x){
                if(++nw==k)return true;
                len=mn;
            }else{
                nw=1;
                len=1<<30;
            }
        }
        return false;
    }
    int main(){
        ios::sync_with_stdio(0),cin.tie(0);
        cin>>n>>k;
        if(k==1)return!printf("%d
    ",n);
        for(int i=1;i<=n;++i)cin>>s[i];
        sa_sort();
        get_height();
        int l=0,r=20001,ans=0;
        while(l<=r){
            int mid=l+r>>1;
            if(check(mid))l=(ans=mid)+1;else
            r=mid-1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    【Vue CLI】手把手教你撸插件
    深入理解web协议(二):DNS、WebSocket
    同城双活与异地多活架构分析
    vivo 商城前端架构升级-总览篇
    原CSDN搬家地址
    PHP 7.1安装xhprof进行性能分析
    nginx配置http和https可同时访问方法, listen ssl与 ssl on区别
    sudo pm2 找不到命令
    HAProxy配置SSL
    docker部署nginx+php的 各种坑
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9605183.html
Copyright © 2011-2022 走看看