zoukankan      html  css  js  c++  java
  • POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203

    后缀数组的买1送2题。。。

    HDU的那题数据实在是太水了,后来才发现在COJ和POJ上都是WA。。原因在一点:在建立sa数组的时候里面的n应该是字符串长度+1.。。。不懂可以去看罗大神的论文。。。

    就是利用后缀数组模板求最长公共子串。


    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define FOR(a,b,i) for(i=a;i<=b;++i)
    #define For(a,b,i) for(i=a;i<b;++i)
    #define N 1000000007
    using namespace std;
    inline void RD(int &ret)
    {
        char c;
        do
        {
            c=getchar();
        }
        while(c<'0'||c>'9');
        ret=c-'0';
        while((c=getchar())>='0'&&c<='9')
        {
            ret=ret*10+(c-'0');
        }
    }
    inline void OT(int a)
    {
        if(a>=10)
        {
            OT(a/10);
        }
        putchar(a%10+'0');
    }
    char f[2000005];
    int rank[1000005],sa[1000005],top[1000005],tmp[1000005],height[1000005],wa[1000005],wb[1000005];
    int cmp(int *r,int a,int b,int l)
    {
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }
    void makesa(int n)//后缀数组模板
    {
        int i,j,p=0,*t,*x=wa,*y=wb,m=300;
        for(i=0; i<m; i++)
        {
            top[i]=0;
        }
        for(i=0; i<n; i++)
        {
            top[x[i]=f[i]]++;
        }
        for(i=1; i<m; i++)
        {
            top[i]+=top[i-1];
        }
        for(i=n-1; i>=0; i--)
        {
            sa[--top[x[i]]]=i;
        }
        for(j=1; p<n; j+=j,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++)
            {
                tmp[i]=x[y[i]];
            }
            for(i=0; i<m; i++)
            {
                top[i]=0;
            }
            for(i=0; i<n; i++)
            {
                top[tmp[i]]++;
            }
            for(i=1; i<m; i++)
            {
                top[i]+=top[i-1];
            }
            for(i=n-1; i>=0; i--)
            {
                sa[--top[tmp[i]]]=y[i];
            }
            for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1; i<n; i++)
            {
                x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
            }
        }
    }
    void makeheight(int n)
    {
    
        int j,i,k;
        for(i=1; i<=n; i++)
        {
            rank[sa[i]]=i;
        }
        for(i=0,k=0; i<n; height[rank[i++]]=k)
        {
            for(k?k--:0,j=sa[rank[i]-1]; f[i+k]==f[j+k]; k++);
        }
    }
    int main()
    {
        int i,l,ll,sum;
        while(scanf("%s",f)!=EOF)
        {
            ll=strlen(f);
            l=ll;
            f[ll]='&';
            scanf("%s",f+l+1);
            ll=strlen(f);
            makesa(ll+1);//就是这里啊,一语惊醒梦中人
            makeheight(ll);
            sum=0;
            for(i=2;i<ll;++i)
            {
                if(height[i]>sum)
                {
                    if((sa[i]>l&&sa[i-1]<l)||(sa[i]<l&&sa[i-1]>l))
                    {
                        sum=height[i];
                    }
                }
            }
            OT(sum);
            printf("
    ");
        }
        return 0;
    }


  • 相关阅读:
    Python必须知道的异常处理
    类的内置方法(用实际代码来验证)
    类的三大特性(继承, 封装, 多态)
    面向对象编程代码详解(依赖关系,关联关系,组合关系)
    函数(匿名函数,嵌套函数,高阶函数,装饰器)
    常用模块
    对磁盘文件的操作(文件处理)
    字符编码
    常用数据类型
    编程介绍
  • 原文地址:https://www.cnblogs.com/pangblog/p/3275596.html
Copyright © 2011-2022 走看看