• poj 3261


    秒掉2/8的男人...

    这题也是考察的后缀数组基础应用:可重叠至少重复k次的最长子串

    显然还是对height数组应用于二分答案的检验

    二分一个长度,然后用height数组检验即可

    注意:不能单纯看height数组中出现某个值的次数,而是要关注height数组中连续出现某个值的次数,否则无法判断这个公共前缀是否相同

    代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    int sa[20005];
    int rank[20005];
    int height[20005];
    int s[20005];
    int a[20005];
    int f1[20005];
    int f2[20005];
    int f3[20005];
    int to[1000005];
    int has[20010];
    int l,k,m=20003;
    void turnit()
    {
        memcpy(f3,f1,sizeof(f3));
        memcpy(f1,f2,sizeof(f1));
        memcpy(f2,f3,sizeof(f2));
    }
    void get_sa()
    {
        for(int i=1;i<=l;i++)
        {
            f1[i]=s[i];
            has[s[i]]++;
        }
        for(int i=2;i<=m;i++)
        {
            has[i]+=has[i-1];
        }
        for(int i=l;i>=1;i--)
        {
            sa[has[f1[i]]--]=i;
        }
        for(int k=1;k<=l;k<<=1)
        {
            int cnt=0;
            for(int i=l-k+1;i<=l;i++)
            {
                f2[++cnt]=i;
            }
            for(int i=1;i<=l;i++)
            {
                if(sa[i]>k)
                {
                    f2[++cnt]=sa[i]-k;
                }
            }
            for(int i=1;i<=m;i++)
            {
                has[i]=0;
            }
            for(int i=1;i<=l;i++)
            {
                has[f1[i]]++;    
            }
            for(int i=2;i<=m;i++)
            {
                has[i]+=has[i-1];
            }
            for(int i=l;i>=1;i--)
            {
                sa[has[f1[f2[i]]]--]=f2[i];
                f2[i]=0;
            }
            turnit();
            f1[sa[1]]=1;
            cnt=1;
            for(int i=2;i<=l;i++)
            {
                if(f2[sa[i]]==f2[sa[i-1]]&&f2[sa[i]+k]==f2[sa[i-1]+k])
                {
                    f1[sa[i]]=cnt;
                }else
                {
                    f1[sa[i]]=++cnt;
                }
            }
            if(cnt==l)
            {
                break;
            }
            m=cnt;
        }
        for(int i=1;i<=l;i++)
        {
            rank[sa[i]]=i;
        }
        int f=0;
        for(int i=1;i<=l;i++)
        {
            if(rank[i]==1)
            {
                continue;
            }
            if(f)
            {
                f--;
            }
            int j=sa[rank[i]-1];
            while(s[i+f]==s[j+f])
            {
                f++;
            }
            height[rank[i]]=f;
        }
    }
    bool check(int v)
    {
        int cnt=0;
        for(int i=2;i<=l;i++)
        {
            if(height[i]>=v)
            {
                cnt++;
                if(cnt>=k-1)
                {
                    return 1;
                }
            }else
            {
                cnt=0;
            }
        }
        return 0;
    }
    int divi()
    {
        int lq=0,rq=l;
        int ans=0;
        while(lq<=rq)
        {
            int mid=(lq+rq)>>1;
            if(check(mid))
            {
                ans=mid;
                lq=mid+1;
            }else
            {
                rq=mid-1;
            }
        }
        return ans;
    }
    int main()
    {
        scanf("%d%d",&l,&k);
        for(int i=1;i<=l;i++)
        {
            scanf("%d",&s[i]);
            a[i]=s[i];
        }
        sort(a+1,a+l+1);
        int tot=1;
        for(int i=1;i<=l;i++)
        {
            if(a[i]==a[i-1])
            {
                to[a[i]]=tot;
            }else
            {
                to[a[i]]=++tot;
            }
        }
        for(int i=1;i<=l;i++)
        {
            s[i]=to[s[i]];
        }
        get_sa();
        printf("%d
    ",divi());
        return 0;
    }
  • 相关阅读:
    elipse图标注解
    Thrift源码解析--transport
    IDL和生成代码分析
    thrift概述
    less分页阅读
    this与super使用总结(java)
    more分页阅读
    Arrays
    Teigha克隆db的blockTableRecord里面的一个实体
    Teigha的BlockTableRecord获取方法
  • 原文地址:https://www.cnblogs.com/zhangleo/p/9707896.html
Copyright © 2020-2023  润新知