传送门

解题思路

这是一个神奇的算法,sa[i]表示排名第i为的元素是啥,rk[i]表示第i个元素排名是啥。然后使用基数排序+倍增的思想去处理。主要是参考的这位大佬的博客(https://www.cnblogs.com/victorique/p/8480093.html#autoid-1-3-4)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>using namespace std;
const int MAXN = 1e6+5;int sa[MAXN],x[MAXN],y[MAXN];
int num,c[MAXN],n,m;
int rk[MAXN],height[MAXN];
char s[MAXN];inline void Get_SA(){for(register int i=2;i<=m;i++) c[i]+=c[i-1];for(register int i=n;i;i--) sa[c[x[i]]--]=i;for(register int k=1;k<=n;k<<=1){num=0;for(register int i=n-k+1;i<=n;i++) y[++num]=i;for(register int i=1;i<=n;i++)if(sa[i]>k) y[++num]=sa[i]-k;for(register int i=2;i<=m;i++) c[i]=0;for(register int i=1;i<=n;i++) c[x[i]]++;for(register int i=2;i<=m;i++) c[i]+=c[i-1];for(register int i=n;i;i--)sa[c[x[y[i]]]--]=y[i],y[i]=0;
//      for(register int i=1;i<=n;i++)
//          cout<<sa[i]<<" ";
//      cout<<endl;swap(x,y);num=1;x[sa[1]]=1;for(register int i=2;i<=n;i++){if(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])x[sa[i]]=num;else x[sa[i]]=++num;}if(num==n) return;m=num;}
}inline void Get_height(){for(register int i=1;i<=n;i++) rk[sa[i]]=i;
//  for(register int i=1;i<=n;i++) cout<<rk[i]<<" ";int k=0,j=0;for(register int i=1;i<=n;i++){if(rk[i]==1) continue;if(k) k--;j=sa[rk[i]-1];while(j+k<=n && i+k<=n && s[i+k]==s[j+k]) k++;height[rk[i]]=k;}for(register int i=1;i<=n;i++)cout<<height[i]<<" ";
}int main(){scanf("%s",s+1);n=strlen(s+1);m=(int)'z';for(register int i=1;i<=n;i++){x[i]=s[i];c[x[i]]++;}Get_SA();for(register int i=1;i<=n;i++)printf("%d ",sa[i]);
//  Get_height();return 0;
}

转载于:https://www.cnblogs.com/sdfzsyq/p/9676933.html

LUOGU 3089 后缀排序(模板)相关推荐

  1. 后缀数组 java实现_后缀数组模板 - java开发指南博客 【转载】 - ITeye博客

    //后缀数组模板 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];//这些都是需要用到的中间变量 int cmp(int *r,int a,int b,int l) { ...

  2. luogu P4512 多项式除法 (模板题、FFT、多项式求逆)

    luogu P4512 多项式除法 (模板题.FFT.多项式求逆) 手动博客搬家: 本文发表于20181206 14:42:53, 原地址https://blog.csdn.net/suncongbo ...

  3. luogu P4726 多项式指数函数(模板题FFT、多项式求逆、多项式对数函数)

    luogu P4726 多项式指数函数(模板题FFT.多项式求逆.多项式对数函数) 手动博客搬家: 本文发表于20181127 08:39:42, 原地址https://blog.csdn.net/s ...

  4. luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)

    luogu P4725 多项式对数函数 (模板题.FFT.多项式求逆.求导和积分) 手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/s ...

  5. 最短工期 (25 分)【拓扑排序模板】

    立志用最少的代码做最高效的表达 一个项目由若干个任务组成,任务之间有先后依赖顺序.项目经理需要设置一系列里程碑,在每个里程碑节点处检查任务的完成情况,并启动后续的任务.现给定一个项目中各个任务之间的关 ...

  6. 【BZOJ 1031】[JSOI2007]字符加密Cipher(后缀数组模板)

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1031 [题意] [题解] 后缀数组模板题; 把整个字符串扩大一倍. 即长度乘2 然后搞 ...

  7. luogu 1327 数列排序 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 J题 循环节

    luogu 1327 数列排序 题意 给定一个数列\(\{an\}\),这个数列满足\(ai≠aj(i≠j)\),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? ...

  8. Kahn拓扑排序模板

    Kahn拓扑排序模板 O(V+E) #include<bits/stdc++.h> using namespace std;typedef long long ll; const int ...

  9. UOJ #35. 后缀排序 后缀数组 模板

    http://uoj.ac/problem/35 模板题,重新理了一遍关系.看注释吧.充分理解了倍增的意义,翻倍之后对上一次排序的利用是通过一种类似于队列的方式完成的. 1 #include<i ...

最新文章

  1. 高斯-勒让德公式 求积分
  2. php web server部署(PHP+Nginx+Redis+MySQL)
  3. Linux环境下虚拟环境virtualenv安装和使用(转)
  4. Kotlin实战指南十一:扩展函数
  5. Python第二十天 shutil 模块 zipfile tarfile 模块
  6. mysql初体验学习笔记_MySQL数据库初体验
  7. oracle服务器重启后监听启动
  8. 19软件班专业英语学期总结
  9. kali linux 模板文件夹,详解kali linux 常用文件与指令路径
  10. myeclipse----JVM运行内存溢出问题解决
  11. 输出匹配项:grep
  12. Swift 可选(Optionals)类型
  13. Winxp系统文件夹完全解析
  14. c语言写的fft程序,C语言编写FFT程序.pdf
  15. CSS选择器的权重计算
  16. Lab: Exploiting XSS to perform CSRF:利用XSS执行CSRF
  17. 跨考计算机日程记录01
  18. C#时间格式化显示AM/PM
  19. pytorch股票预测
  20. SuperEmper技术支持

热门文章

  1. linux安装redis 完整步骤
  2. concurrent(六)同步辅助器CyclicBarrier 源码分析
  3. Bootstrap File Input 真正 解决跨域问题
  4. ubuntu lamp配置多域名服务器
  5. Android——Handler总结
  6. setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto
  7. jquery内核学习(6)--扩展实现extend
  8. cmake用法及常用命令总结(全)
  9. Kotlin——初级篇(六):空类型、空安全、非空断言、类型转换等特性总结
  10. mysql重复数据查询