zoukankan      html  css  js  c++  java
  • codevs1500 后缀排序

    题目描述 Description

    天凯是MIT的新生。Prof. HandsomeG给了他一个长度为n的由小写字母构成的字符串,要求他把该字符串的n个后缀(suffix)从小到大排序。

    何谓后缀?假设字符串是S=S1S2……Sn,定义Ti=SiSi+1……Sn。T1, T2, …, Tn就叫做S的n个后缀。

    关于字符串大小的比较定义如下(比较规则和PASCAL中的定义完全相同,熟悉PASCAL的同学可以跳过此段):

    若A是B的前缀,则A<B;否则令p满足:A1A2…Ap-1=B1B2…Bp-1,Ap<>Bp。如果Ap<Bp,则A<B;否则A>B。

    输入描述 Input Description

    第一行一个整数n(n<=15000)

    第二行是一个长度为n字串。

    输出描述 Output Description

    输出文件包含n行,第i行是一个整数pi。表示所有的后缀从小到大排序后是Tp1, Tp2, …, Tpn。

    样例输入 Sample Input

    4

    abab

    样例输出 Sample Output

    3

    1

    4

    2

    数据范围及提示 Data Size & Hint

    说明:后缀排序后的顺序是T3=”ab”, T1=”abab”, T4=”b”, T2=”bab”。所以输出是3, 1, 4, 2。

    正解:后缀数组

    解题报告:

      后缀数组模板题

      

     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXN = 300011;
    21 char ch[MAXN];
    22 int n,m,tot;
    23 int wa[MAXN],wb[MAXN],wv[MAXN],c[MAXN];
    24 int rank[MAXN],height[MAXN];
    25 int sa[MAXN];
    26 
    27 inline int getint()
    28 {
    29        int w=0,q=0;
    30        char c=getchar();
    31        while((c<'0' || c>'9') && c!='-') c=getchar();
    32        if (c=='-')  q=1, c=getchar();
    33        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    34        return q ? -w : w;
    35 }
    36 
    37 inline void da(int m){
    38     int i,*x=wa,*y=wb;
    39     for(i=1;i<=m;i++) c[i]=0;
    40     for(i=1;i<=n;i++) c[x[i]=(ch[i]-'a'+1)]++;
    41     for(i=1;i<=m;i++) c[i]+=c[i-1];
    42     for(i=n;i>=1;i--) sa[c[x[i]]--]=i;
    43     for(int k=1,p;k<=n;k=k*2) {
    44     p=0;
    45     for(i=n-k+1;i<=n;i++) y[++p]=i;
    46     for(i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;
    47     for(i=1;i<=m;i++) c[i]=0;
    48     for(i=1;i<=n;i++) c[x[y[i]]]++;     
    49     for(i=1;i<=m;i++) c[i]+=c[i-1];
    50     for(i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i];
    51     swap(x,y);  x[sa[1]]=1; p=1;
    52     for(i=2;i<=n;i++) x[sa[i]]=(y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k])?p:++p;
    53     if(p==n) break; m=p;
    54     }
    55 }
    56 
    57 inline void calheight(){
    58     int i,j,k=0;
    59     for(i=1;i<=n;height[rank[i++]]=k)
    60     for(k?k--:0 , j=sa[rank[i]-1];ch[i+k]==ch[j+k];k++) ;
    61 }
    62 
    63 inline void work(){
    64     scanf("%s",ch+1);   n=strlen(ch+1);
    65     da(256);
    66     for(int i=1;i<=n;i++) rank[sa[i]]=i;
    67     calheight();
    68     for(int i=1;i<=n;i++) printf("%d ",sa[i]);
    69     printf("
    ");
    70     for(int i=2;i<=n;i++) printf("%d ",height[i]);
    71 }
    72 
    73 int main()
    74 {
    75   work();
    76   return 0;
    77 }
  • 相关阅读:
    HDU 5640 King's Cake
    HDU 5615 Jam's math problem
    HDU 5610 Baby Ming and Weight lifting
    WHU1604 Play Apple 简单博弈
    HDU 1551 Cable master 二分
    CodeForces659C Tanya and Toys map
    Codeforces 960E 树dp
    gym 101485E 二分匹配
    Codeforces 961E 树状数组,思维
    Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5657408.html
Copyright © 2011-2022 走看看