• luogu3809 后缀排序 后缀数组


    ref and 挑战程序设计竞赛。
    主要是发现自己以前写得代码太难看而且忘光了,而且我字符串死活学不会啊,kmp这种东西我都觉得是省选+难度啊QAQ

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    int n, cnt[1000005], rnk[1000005], saa[1000005], tmp[1000005], m=128, p;
    char ss[1000005];
    void sasort(){
    	for(int i=0; i<m; i++)	cnt[i] = 0;
    	for(int i=0; i<n; i++)	cnt[rnk[i]]++;
    	for(int i=1; i<m; i++)	cnt[i] += cnt[i-1];
    	for(int i=n-1; i>=0; i--)	saa[--cnt[rnk[tmp[i]]]] = tmp[i];//大约就是rnk[i](第一关键字排序后的下标数组)定了一段一段的位置以后,依据第二关键字精确确定位置
    }
    void getSuffixArray(){
    	for(int i=0; i<n; i++){
    		rnk[i] = ss[i];
    		tmp[i] = i;
    	}
    	sasort();
    	for(int j=1; p<n; j<<=1){
    		p = 0;
    		for(int i=n-j; i<n; i++)	tmp[p++] = i;
    		for(int i=0; i<n; i++)
    			if(saa[i]>=j)
    				tmp[p++] = saa[i] - j;//构造第二关键字数组,tmp[0]表示第二关键字最小(第0小)的元素位置i,(也就是i+j..n这样的后缀最小),以此类推
    		sasort();
    		swap(rnk, tmp);//因为以前的rank也要用到
    		p = 1;
    		rnk[saa[0]] = 0;
    		for(int i=1; i<n; i++)
    			if(tmp[saa[i-1]]==tmp[saa[i]] && tmp[saa[i-1]+j]==tmp[saa[i]+j])//这里是不会越界的……
    				rnk[saa[i]] = p - 1;
    			else
    				rnk[saa[i]] = p++;
    		m = p;//p代表有多少种rank,m代表字符集个数
    	}
    }
    int main(){
    	scanf("%s", ss);
    	n = strlen(ss);
    	ss[n++] = 0;
    	getSuffixArray();
    	for(int i=1; i<n; i++)
    		printf("%d ", saa[i]+1);
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    矩阵快速幂模板
    Kuangbin带你飞 AC自动机
    Kuangbin 带你飞 KMP扩展KMP Manacher
    Kuangbin 带你飞 数位DP题解
    kuangbin 带你飞 数学基础
    Kuangbin 带你飞-基础计算几何专题 题解
    最大团问题
    头文件
    Codeforces 362E Petya and Pipes 费用流建图
    kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树
  • 原文地址:https://www.cnblogs.com/poorpool/p/8252336.html
Copyright © 2020-2023  润新知