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

    贴模板

    注意:( ext{id}) 表示第二关键字排序后(其实无需排序,利用上轮的 ( ext{sa}) 值即可)相应的第一关键字的位置
    计数排序为了稳定性最后确定位置时要倒着开始
    复制的 ( ext{ork}) 要开两倍

    ( ext{Code})

    #include <cstdio>
    #include <cstring>
    #define re register
    using namespace std;
    
    const int N = 1e6 + 5;
    int n, sa[N], rk[N], cnt[N], id[N], ork[N << 1];
    char s[N];
    
    inline int comp(int x, int y, int w){return (ork[x] == ork[y]) && (ork[x + w] == ork[y + w]);}
    
    inline void build_SA()
    {
    	int m = 300, p;
    	for(re int i = 1; i <= n; i++) ++cnt[rk[i] = s[i]];
    	for(re int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
    	for(re int i = n; i; i--) sa[cnt[rk[i]]--] = i;
    	
    	for(re int w = 1; w < n; w <<= 1, m = p)
    	{
    		p = 0;
    		for(re int i = n - w + 1; i <= n; i++) id[++p] = i;
    		for(re int i = 1; i <= n; i++)
    		if (sa[i] > w) id[++p] = sa[i] - w;
    		
    		for(re int i = 0; i <= m; i++) cnt[i] = 0;
    		for(re int i = 1; i <= n; i++) ++cnt[rk[id[i]]];
    		for(re int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
    		for(re int i = n; i; i--) sa[cnt[rk[id[i]]]--] = id[i];
    		
    		for(re int i = 1; i <= n; i++) ork[i] = rk[i];
    		p = 0;
    		for(re int i = 1; i <= n; i++)
    		rk[sa[i]] = comp(sa[i], sa[i - 1], w) ? p : ++p;
    		if (p >= n) break;
    	}
    }
    
    int main()
    {
    	scanf("%s", s + 1), n = strlen(s + 1), build_SA();
    	for(re int i = 1; i <= n; i++) printf("%d ", sa[i]);
    }
    
  • 相关阅读:
    本地SQL密码破解
    SqlServer2005复制分类
    xpsql.cpp: 错误 2 来自 CreateProcess(第 737 行)
    sql server 复制,镜像,日志传输及故障转移集群区别
    使用SQL操作MySQL数据库
    [技术文摘]Resin服务器的使用
    Tomcat新手攻略
    Java连接数据库谈
    jsp中文乱码问题的解决2
    台风来到
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15138906.html
Copyright © 2011-2022 走看看