poj 3261 Milk Patterns 【后缀数组】

原创 2012年03月22日 10:38:21

给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠。
算法分析:
这题的做法和上一题差不多,也是先二分答案,然后将后缀分成若干组。不同的是,这里要判断的是有没有一个组的后缀个数不小于 k。如果有,那么存在k 个相同的子串满足条件,否则不存在。这个做法的时间复杂度为 O(nlogn)

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

const int maxn=20010;
int a[maxn],b[maxn],s[maxn],c[maxn];
int *rank,*height,*sa=s+1;

void sortandrank(int *a1,int *a2,int n,int &m,int j)
{
    int i;memset(c,0,sizeof(c));
    for(i=0;i<n;i++) c[a1[i]]++;
    for(i=1;i<=m;i++) c[i]+=c[i-1];
    for(i=n-1;i>=0;i--) sa[--c[a1[a2[i]]]]=a2[i];
    a2[sa[0]]=m=0;
    for(i=1;i<n;i++) a2[sa[i]]=a1[sa[i-1]]==a1[sa[i]]&&a1[sa[i-1]+j]==a1[sa[i]+j]?m:++m;
}
void da(int*str,int n,int m)
{
    int *a1=a,*a2=b,*tmp;
    int i,j,p;
    for(i=0;i<n;i++) a1[i]=i,a2[i]=str[i];
    a1[n]=a2[n]=-1;
    sortandrank(a2,a1,n,m,0);
    for(j=1;m<n-1;j<<=1)
    {
        p=0;
        for(i=n-j;i<n;i++) a2[p++]=i;
        for(i=0;i<n;i++) if(sa[i]>=j) a2[p++]=sa[i]-j;
        sortandrank(a1,a2,n,m,j);
        tmp=a1,a1=a2,a2=tmp;
    }
    rank=a1,height=a2;
}
void calheight(int*str,int n)
{
    int i,j,k;
    sa[-1]=n;
    for(height[0]=k=i=0;i<n;i++)
    {
        for(k?k--:0,j=sa[rank[i]-1];str[i+k]==str[j+k];k++);
        height[rank[i]]=k;
    }
}
int hash[1000005],num[maxn],m=1;
bool chk(int mid,int n,int k)
{
    int cnt=0;
    for(int i=2;i<=n;i++)
    {
        if(height[i]<mid) cnt=0;
        else cnt++;
        if(cnt>=k) return 1;
    }
    return 0;
}
int main()
{
    int n,k,x;
    //memset(hash,-1,sizeof(hash));
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        if(hash[x]==0) hash[x]=m++;
        num[i]=hash[x];
    }
    da(num,n+1,m);calheight(num,n);
    //for(int i=0;i<=n;i++) cout<<height[i]<<' '<<sa[i]<<endl;
    int l=0,r=n,mid,ans=0;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(chk(mid,n,k-1)) l=mid+1,ans=mid;
        else r=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

【POJ3261】Milk Patterns 后缀数组

水题不好意思说题解。 说说题意吧: 给一个字符串(数字串),然后求最长k次重复子串。 即某串在字符串中重复了至少k次,求这种串的最长长度。 代码: #include #in...

【POJ】3261 Milk Patterns 【后缀数组】

传送门:【POJ】3261 Milk Patterns 题目分析:构好后缀数组,然后二分答案就好了~_~ 代码如下: #include #include #include using...

POJ 3261 Milk Patterns (离散化+后缀数组 可重叠k次最长重复子串)

题意:给出一串长度为n的字符,再给出一个k值,要你求重复次数大于等于k次的最长子串长度 思路:首先离散化,然后采用后缀数组的常用处理方法,二份答案,按照二份值k将height数组分组,对于k是否可行...

POJ 3261 Milk Patterns(后缀数组 重复出现K次字串的长度)

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7956   ...

poj 3261 Milk Patterns 后缀数组+二分

题意是求可以重复的出现次数超过k次的子串,最长是多少。 样例输入 8 2 1 2 3 2 3 2 3 1 输出 4 二分验证是否有连续的k-1个height大于所验证的答案...
  • Loi_a
  • Loi_a
  • 2016-12-27 08:03
  • 129

POJ 3261 Milk Patterns 最长出现k次的子串长度(后缀数组)

Milk PatternsTime Limit: 5000MS Memory Limit: 65536K DescriptionFarmer John has noticed that t...
  • w4149
  • w4149
  • 2017-07-27 19:36
  • 58

poj 3261 Milk Patterns (后缀数组)

poj 3261 Milk Patterns 题意: 给定一个字符串S,求至少出现k次的最长重复子串,这k个子串可以重叠。 限制: 1 思路: 二分答案长度用lcp判断 ...

POJ 3261 Milk Patterns【后缀数组】可重叠的k次最长子串

Description Farmer John has noticed that the quality of milk given by his cows varies from day t...

POJ 3261 Milk Patterns 后缀数组

Description Farmer John has noticed that the quality of milk given by his cows varies from day to d...

POJ3261 Milk Patterns(后缀数组,二分)

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 15837   ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)