• poj 3415 后缀数组 两个字符串中长度不小于 k 的公共子串的个数


    Common Substrings
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 11469   Accepted: 3796

    Description

    A substring of a string T is defined as:

    T(ik)=TiTi+1...Ti+k-1, 1≤ii+k-1≤|T|.

    Given two strings AB and one integer K, we define S, a set of triples (ijk):

    S = {(ijk) | kKA(ik)=B(jk)}.

    You are to give the value of |S| for specific AB and K.

    Input

    The input file contains several blocks of data. For each block, the first line contains one integer K, followed by two lines containing strings A and B, respectively. The input file is ended by K=0.

    1 ≤ |A|, |B| ≤ 105
    1 ≤ K ≤ min{|A|, |B|}
    Characters of A and B are all Latin letters.

    Output

    For each case, output an integer |S|.

    Sample Input

    2
    aababaa
    abaabaa
    1
    xx
    xx
    0
    

    Sample Output

    22
    5
    

    Source

    题意:
    给定两个字符串 A 和 B,求长度不小于 k 的公共子串的个数(可以相同)
    代码:
    //论文题,按照规矩先把两个串连起来求出heigh数组,heigh数组分组(大于等于k的一组),然后每遇到一个B串就让他和前面的A串求
    //lcp,贡献就是lcp-k+1,然后反过来再求一次每个A和前面的B的,但这是n^2的。我们考虑求某个B与前面的A的lcp时是求这一段中的最小
    //的heigh值,这样我们可以用一个递增的栈来存储heigh数组把贡献叠加起来,要入栈的元素小于栈顶时对后面的B的贡献值会减小,并且
    //还要保存因为他的入栈而出栈了多少大于等于他的元素以备后面的操作(减小贡献值),每遇到B就更新答案。
    //这题还是很难的
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int MAXN=300000;
    int sa[MAXN+9],he[MAXN+9],ra[MAXN+9],xx[MAXN+9],yy[MAXN+9],buc[MAXN+9],q[MAXN+9][2];
    char s[MAXN+9];
    int len,m;
    void get_suf()
    {
        int *x=xx,*y=yy;
        for(int i=0;i<m;i++) buc[i]=0;
        for(int i=0;i<len;i++) buc[x[i]=s[i]]++;
        for(int i=1;i<m;i++) buc[i]+=buc[i-1];
        for(int i=len-1;i>=0;i--) sa[--buc[x[i]]]=i;
        for(int k=1;k<=len;k<<=1){
            int p=0;
            for(int i=len-1;i>=len-k;i--) y[p++]=i;
            for(int i=0;i<len;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
            for(int i=0;i<m;i++) buc[i]=0;
            for(int i=0;i<len;i++) buc[x[y[i]]]++;
            for(int i=1;i<m;i++) buc[i]+=buc[i-1];
            for(int i=len-1;i>=0;i--) sa[--buc[x[y[i]]]]=y[i];
            swap(x,y);
            p=1;x[sa[0]]=0;
            for(int i=1;i<len;i++){
                if(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k])
                    x[sa[i]]=p-1;
                else x[sa[i]]=p++;
            }
            if(p>=len) break;
            m=p;
        }
        for(int i=0;i<len;i++) ra[sa[i]]=i;
        int k=0;
        for(int i=0;i<len;i++){
            if(ra[i]==0) { he[0]=0; continue; }
            if(k) k--;
            int j=sa[ra[i]-1];
            while(s[i+k]==s[j+k]&&i+k<len&&j+k<len) k++;
            he[ra[i]]=k;
        }
    }
    ll solve(int len1,int k)
    {
        ll ans=0,cnt=0,sum=0,top=0;
        for(int i=1;i<len;i++){
            if(he[i]<k) { top=sum=0;continue; }
            cnt=0;
            if(sa[i-1]<len1) { cnt++;sum+=he[i]-k+1; }
            while(top&&he[i]<=q[top][1]){
                sum-=q[top][0]*(q[top][1]-he[i]);
                cnt+=q[top--][0];
            }
            q[++top][0]=cnt;
            q[top][1]=he[i];
            if(sa[i]>len1) ans+=sum;
        }
        sum=0;top=0;
        for(int i=1;i<len;i++){
            if(he[i]<k) { top=sum=0;continue; }
            cnt=0;
            if(sa[i-1]>len1) { cnt++;sum+=he[i]-k+1; }
            while(top&&he[i]<=q[top][1]){
                sum-=q[top][0]*(q[top][1]-he[i]);
                cnt+=q[top--][0];
            }
            q[++top][0]=cnt;
            q[top][1]=he[i];
            if(sa[i]<len1) ans+=sum;
        }
        return ans;
    }
    int main()
    {
        int k;
        while(scanf("%d",&k)&&k){
            scanf("%s",s);
            int len1=strlen(s);
            s[len1]='#';
            scanf("%s",s+len1+1);
            len=strlen(s);
            m=200;
            get_suf();
            printf("%lld
    ",solve(len1,k));
        }
        return 0;
    }
  • 相关阅读:
    Enterprise Library 4.1学习笔记2数据访问程序块
    [转]Using The Silverlight DataGrid
    Enterprise Library 4.1学习笔记6加密应用程序块
    servU 7以上版本pasv端口的设置及中文乱码问题
    [转]深度解析 TypeConverter & TypeConverterAttribute
    MVC RC2中关于HtmlHelper给DropDownList设置初始选中值的问题
    [转]php5+apache2+mysql5最新环境配置
    WCF运行错误:“此集合已经包含方案 http 的地址”的解决办法
    silverlight + wcf(json格式) + sqlserver存储过程分页
    [转贴]Http 请求处理流程
  • 原文地址:https://www.cnblogs.com/--ZHIYUAN/p/7619935.html
Copyright © 2020-2023  润新知