zoukankan      html  css  js  c++  java
  • P3809 【模板】后缀排序

    题面

    https://www.luogu.org/problem/P3809

    题解

    好像写的时候还不理解,但是现在理解了。

    排序是间接排序:对于每个点对它的位置$+1$,表示这个位置具有的点的个数,再求前缀和,最后一个一个减回去,得到排名。

    对于双关键字的情况,排两次序,先第二再第一。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define N 1000050
    #define ri register int
    
    using namespace std;
    char s[N];
    int n,m;
    int sa[N],rank[N],tp[N],tax[N];
    
    void cntsort(){
      for (ri i=0;i<=m;i++) tax[i]=0;
      for (ri i=1;i<=n;i++) tax[rank[i]]++;
      for (ri i=1;i<=m;i++) tax[i]+=tax[i-1];
      for (ri i=n;i>=1;i--) sa[tax[rank[tp[i]]]--]=tp[i]; /**/
    }
    
    void Suffixsort(){
      m=75;
      for (ri i=1;i<=n;i++) rank[i]=s[i]-'0'+1,tp[i]=i; /**/
      cntsort();
      for (ri w=1,p=0;p<n;m=p,w<<=1) {
        p=0;
        for (ri i=1;i<=w;i++) tp[++p]=n-w+i;
        for (ri i=1;i<=n;i++) if (sa[i]>w) tp[++p]=sa[i]-w;
        cntsort();
        swap(tp,rank); // tp rank not tp sa
        rank[sa[1]]=p=1; // low
        for (ri i=2;i<=n;i++) { // 2
          rank[sa[i]]=(tp[sa[i-1]]==tp[sa[i]] && tp[sa[i-1]+w]==tp[sa[i]+w]) ? p : ++p;
        }
      }
    }
    
    int main(){
      scanf("%s",s+1);
      n=strlen(s+1);
      Suffixsort();
      //cout<<n<<endl;
      for (ri i=1;i<=n;i++) printf("%d ",sa[i]);
    }
  • 相关阅读:
    StrUtils
    WebUtil
    TreeUtil
    SQL解决表结构不同的数据同步方案
    MongoDB还原备份Bson文件及导出SQL文件
    Tengine安装步骤
    C++_练习—多态_virtual
    C++_练习—this指针
    C++_练习—继承_构造初始化列表
    C++_练习—继承_构造析构
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11426303.html
Copyright © 2011-2022 走看看