zoukankan      html  css  js  c++  java
  • [UOJ35]后缀排序

    [UOJ35]后缀排序

    题目大意:

    对于给定的长度为(n(nle10^6))的字符串求后缀数组(sa[i])和高度数组(lcp[i])

    思路:

    倍增+快排构造后缀数组,利用(rank[i])(lcp[i])。时间复杂度(mathcal O(nlog^2 n))

    源代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int N=1e5+1;
    char s[N];
    int n,k,sa[N],rank[N],tmp[N],lcp[N];
    inline bool cmp(const int &i,const int &j) {
    	if(rank[i]!=rank[j]) return rank[i]<rank[j];
    	const int ri=i+k<=n?rank[i+k]:-1;
    	const int rj=j+k<=n?rank[j+k]:-1;
    	return ri<rj;
    }
    inline void suffix_sort() {
    	for(register int i=0;i<=n;i++) {
    		sa[i]=i;
    		rank[i]=s[i];
    	}
    	for(k=1;k<=n;k<<=1) {
    		std::sort(&sa[0],&sa[n]+1,cmp);
    		tmp[sa[0]]=0;
    		for(register int i=1;i<=n;i++) {
    			tmp[sa[i]]=tmp[sa[i-1]]+!!cmp(sa[i-1],sa[i]);
    		}
    		std::copy(&tmp[0],&tmp[n]+1,rank);
    	}
    }
    inline void init_lcp() {
    	for(register int i=0,h=0;i<n;i++) {
    		if(h>0) h--;
    		const int j=sa[rank[i]-1];
    		while(j+h<n&&i+h<n&&s[j+h]==s[i+h]) h++;
    		lcp[rank[i]-1]=h;
    	}
    }
    int main() {
    	scanf("%s",s);
    	n=strlen(s);
    	suffix_sort();
    	init_lcp();
    	for(register int i=1;i<=n;i++) {
    		printf("%d%c",sa[i]+1," 
    "[i==n]);
    	}
    	for(register int i=1;i<n;i++) {
    		printf("%d%c",lcp[i]," 
    "[i==n-1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    LinkedListQueue
    LinkedListStack
    redis学习之——Redis事务(transactions)
    redis学习之——持久化RDB 和AOF
    redis学习之——redis.conf配置(基本)文件学习
    评估算法的核心指标
    Vector类
    List接口与ArrayList、LinkedList实现类
    Collection接口
    枚举类
  • 原文地址:https://www.cnblogs.com/skylee03/p/9172684.html
Copyright © 2011-2022 走看看