zoukankan      html  css  js  c++  java
  • 洛谷P3809 后缀数组模板

    题目:https://www.luogu.org/problemnew/show/P3809

    刚学了后缀数组,看人家手写演示了半天,大概明白了过程,但完全写不出来代码;

    于是借鉴了许多,不过都差不多,总算会写了;

    如何把想法实现出来很重要啊...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int const maxn=1e6+5;
    int n,m,rk[maxn],tp[maxn],sa[maxn],a[maxn],num,tax[maxn];
    char s[maxn];
    void Rsort()
    {
        for(int i=0;i<=m;i++)tax[i]=0;
        for(int i=1;i<=n;i++)tax[rk[tp[i]]]++;
        for(int i=1;i<=m;i++)tax[i]+=tax[i-1];
        for(int i=n;i;i--)sa[tax[rk[tp[i]]]--]=tp[i];//tp是位置,rk是该位置第一关键字排名,tax存数量 
        //tp[i]是第二关键字从小到大进入,所以从大到小出来就可以使用前缀 
    }
    void work()
    {
        for(int i=1;i<=n;i++)rk[i]=a[i],tp[i]=i;
        Rsort();
        for(int k=1;k<=n;k<<=1)
        {
            num=0;
            for(int i=n-k+1;i<=n;i++)tp[++num]=i;//n-k以后的i后缀第二关键字是0,字典序最小 
            for(int i=1;i<=n;i++)//枚举排名(上一次的,也就是本次第一关键字) 
                if(sa[i]>k)tp[++num]=sa[i]-k;//排名从小到大,其所在位置如果大于k,则可以作为本次第二关键字
                //sa[i]-k 是位置,若上一次的第i名作为本次第二关键字,则所得后缀的位置在sa[i]-k 
            Rsort();
            swap(rk,tp);//tp存下上一次排名,也就是本次第一关键字的排名 
            rk[sa[1]]=1;
            num=1;
            for(int i=2;i<=n;i++)
                rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+k]==tp[sa[i-1]+k])?num:++num;
            //比较前后两半排名是否相同 
            if(num==n)break;
            m=num;//m是种类 
        }
    }
    int main()
    {
        cin>>s;
        n=strlen(s); m=122;
        for(int i=1;i<=n;i++)a[i]=s[i-1];
        work();
        for(int i=1;i<=n;i++)printf("%d ",sa[i]);
        return 0;
    }
  • 相关阅读:
    WHERE col1=val1 AND col2=val2;index exists on col1 and col2, the appropriate rows can be fetched directly
    MySQL 交集 实现方法
    MBProgressHUD的使用
    Xcode4 使用 Organizer 分析 Crash logs(转)
    SimpleXML 使用详细例子
    PHP的XML Parser(转)
    iPhone,iPhone4,iPad程序启动画面的总结 (转)
    Pop3得到的Email 信件格式介绍
    yii总结
    隐藏Tabbar的一些方法
  • 原文地址:https://www.cnblogs.com/Zinn/p/9329820.html
Copyright © 2011-2022 走看看