【sam复习】用sam实现后缀排序
没错,一定是无聊到一定境界的人才能干出这种事情。
这个无聊的zcysky已经不满足于用后缀平衡树求sa了,他想用sam试试。
我们回顾下sam的插入过程,如果我们从最后一个state沿着suffix link向上爬parent tree
那么我们就可以遍历这个sam的所有后缀。
那么我们把插入的时候经历的state全都标记下来,并且记录下这个state对应的序号
在对parent tree进行dfs的时候先序遍历一下就可以了。
#include<bits/stdc++.h>
#define N 300010
using namespace std;
int n,c[N],tot,tota,sacnt,top=,cnt=;
int last=,fa[N],ch[N][],l[N],vis[N],head[N];
int r[N],sa[N],rk[N],h[N];
char s[N];
struct state{int x,y,v;}q[N];
struct Edge{int u,v,next;}G[N<<];
inline void addedge(int u,int v){
G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot;
}
void dfs(int u){
if(r[u])sa[++sacnt]=r[u];
for(int i=head[u];i;i=G[i].next)dfs(G[i].v);
}
void ins(int c,int pos){
int p=last,np=++cnt;last=np;l[np]=l[p]+;r[np]=pos;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=;
else{
int q=ch[p][c];
if(l[p]+==l[q])fa[np]=q;
else{
int nq=++cnt;l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[np]=fa[q]=nq;
for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
}
int main(){
int f=;
scanf("%s",s+);n=strlen(s+);
vis[]=last=cnt=;
for(int i=n;i;i--)ins(s[i]-'a',i);
for(int i=;i<=cnt;i++)if(r[i]&&!vis[i])
for(int pos=n,j=i;!vis[j];vis[j]=,j=fa[j],--pos){
pos=pos-l[j]+l[fa[j]]+;q[++top]=(state){fa[j],j,s[pos]-'a'};
}
for(int i=;i<=top;i++)c[q[i].v]++;
for(int i=;i<;i++)c[i]+=c[i-];
for(int i=top;i;i--)rk[c[q[i].v]--]=i;
for(;top;top--)addedge(q[rk[top]].x,q[rk[top]].y);
dfs();
for(int i=;i<=n;i++)printf("%d ",sa[i]);puts("");
for(int i=;i<=n;i++)rk[sa[i]]=i;
for(int i=;i<=n;i++){
int f=max(h[rk[i-]]-,);
for(int j=sa[rk[i]-];s[i+f]==s[j+f];f++);
h[rk[i]]=f;
}
for(int i=;i<=n;i++)printf("%d ",h[i]);
}
就这样,用sam就把这题水过去了~
【sam复习】用sam实现后缀排序的更多相关文章
- LG3809 【模板】后缀排序
题意 题目背景 这是一道模板题. 题目描述 读入一个长度为 $ n $ 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的 ...
- 关于SAM和广义SAM
关于SAM和广义SAM 不是教程 某些思考先记下来 SAM 终于学会了这个东西诶...... 一部分重要性质 确定一个重要事情,S构造出的SAM的一个重要性质是当且仅当对于S的任意一个后缀,可以从1号 ...
- codevs1500 后缀排序
题目描述 Description 天凯是MIT的新生.Prof. HandsomeG给了他一个长度为n的由小写字母构成的字符串,要求他把该字符串的n个后缀(suffix)从小到大排序. 何谓后缀?假设 ...
- UOJ#35 后缀排序
这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编号为 1 到 n. 除此之外为 ...
- P3809 【模板】后缀排序
P3809 [模板]后缀排序 从这学的 后缀数组sa[i]就表示排名为i的后缀的起始位置 x[i]是第i个元素的第一关键字 y[i]表示第二关键字排名为i的数,在第一关键字中的位置 #include& ...
- 2018.11.24 loj#111. 后缀排序(后缀数组)
传送门 后缀排序模板题. 终于会后缀数组了(然而只会倍增并不会DC3DC3DC3). 在这里列举几个数组的意思: sai:sa_i:sai:当前排名第iii的后缀的起始下标. rkirk_irki ...
- uoj35 后缀排序
题目链接:http://uoj.ac/problem/35 这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第 ...
- codevs 1500 后缀排序
codevs 1500 后缀排序 http://codevs.cn/problem/1500/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 天凯是MI ...
- 洛谷:P3809 【模板】后缀排序(后缀数组模板)
P3809 [模板]后缀排序 题目链接:https://www.luogu.org/problemnew/show/P3809 题目背景 这是一道模板题. 题目描述 读入一个长度为 nn 的由大小写英 ...
- [洛谷P3809]【模板】后缀排序
[洛谷P3809][模板]后缀排序 题目大意: 对于给定的长度为\(n(n\le10^6)\)的字符串求后缀数组\(sa[i]\). 思路: 倍增+快排构造后缀数组.代码参考<挑战程序设计竞赛& ...
随机推荐
- 使用Visual C ++和Open Folder自定义环境
使用Visual C ++和Open Folder自定义环境 来源 https://blogs.msdn.microsoft.com/vcblog/2016/10/05/bring-your-c-co ...
- HDU3949:XOR——题解
http://acm.hdu.edu.cn/showproblem.php?pid=3949 求n个数的异或和第k小. 参考:https://blog.sengxian.com/algorithms/ ...
- 信息工程学院技能大赛 计算机程序设计(Java)大赛试题
前期准备与后期上传工作: (1)必须先建立项目和包,项目名为"JavaContest",包结构为:"contest.c+序号+姓名",其中序号为两位为本人大赛报 ...
- React router 4 获取路由参数,跨页面参数
1. match通过路径 <Route path="/path/:name" component={example} /> 路由组件内获取参数使用 this.props ...
- BZOJ2791 Rendezvous
Description给定一个n个顶点的有向图,每个顶点有且仅有一条出边.对于顶点i,记它的出边为(i, a[i]).再给出q组询问,每组询问由两个顶点a.b组成,要求输出满足下面条件的x.y:1. ...
- Eclipse NDK 打印LOG信息(都在jni目录下操作)
http://blog.csdn.net/u013045971/article/details/46448975 1 在.c文件中,引用头文件,定义TAG.LOG宏: #include <and ...
- requireJs使用方法项目实例
首先,定义 main.js 和 事件处理的公共 js main.js 主要是定义引用名称和路径的对应关系 事件绑定模块: 写jsp页面: jsp中先引入 require.js 和 main.js 然 ...
- Cows POJ - 2481 树状数组
Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can ...
- [zabbix]zabbix分区表操作步骤
Q&A: 1.mul key: . 如果Key是空的, 那么该列值的可以重复, 表示该列没有索引, 或者是一个非唯一的复合索引的非前导列 . 如果Key是PRI, 那么该列是主键的组成部分 . ...
- TCP ------ TCP三次握手(建立连接)及其相关内容
1.TCP客户端要连接到TCP服务器,需要经过三个过程: 以下是通过 Wireshark 抓取的三次握手数据包 → [SYN] Seq= Win= Len= MSS= → [SYN, ACK] Seq ...