• 后缀数据结构模板1


    后缀数据结构太TM毒瘤了

    给定一个字符串s,大小为n,下标从1开始。

    sa[i]代表排名为i的后缀是哪一个。

    rk[i]代表第i个后缀的排名,满足rk[sa[i]]=i。

    h[i]代表第i个后缀的"高度",满足h[i]=height[rk[i]]

    height[i]代表排名为i的后缀与排名为i-1的后缀的lcp,即后缀树上lca的深度。

    下面先用倍增+基数排序法求出后缀数组sa。

    然后求出sa的反数组rk。

    h数组有一个性质:h[i]>=h[i-1]-1。证明:大概是利用后缀树上某一个子树内存储信息比深度较浅的相似的树存储信息少来证明,具体忘了。

    利用这个性质可以在线形时间复杂度内求出h数组。

    然后利用sa和rk数组即可求出height数组。

    在height数组中,排名为i的后缀和排名为j的后缀的(i!=j)lcp为min(height[i+1],height[i+2],...,height[j-1],height[j])

    这是一个rmq问题,如果需要O(1)求出两个后缀的lcp,可以将height数组进行倍增ST处理。

    int n;
    char s[300010];
    int sa[300010], t1[300010], t2[300010], c[300010];
    int rk[300010], height[300010], h[300010]; //height[i] = lca(i - 1, i)
    
    void build(int m)
    {
    	int *x = t1, *y = t2;
    	for (int i = 1; i <= m; i++) c[i] = 0;
    	for (int i = 1; i <= n; i++) c[x[i] = s[i]]++;
    	for (int i = 1; i <= m; i++) c[i] += c[i - 1];
    	for (int i = n; i >= 1; i--) sa[c[x[i]]--] = i;
    	for (int k = 1; k <= n; k <<= 1)
    	{
    		int p = 0;
    		for (int i = n - k + 1; i <= n; i++) y[++p] = i;
    		for (int i = 1; i <= n; i++) if (sa[i] > k) y[++p] = sa[i] - k;
    		for (int i = 1; i <= m; i++) c[i] = 0;
    		for (int i = 1; i <= n; i++) c[x[i]]++;
    		for (int i = 1; i <= m; i++) c[i] += c[i - 1];
    		for (int i = n; i >= 1; i--) sa[c[x[y[i]]]--] = y[i];
    		swap(x, y), p = 1, x[sa[1]] = 1;
    		for (int i = 2; i <= n; i++) x[sa[i]] = (y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k]) ? p : ++p;
    		if (p >= n) break;
    		m = p;
    	}
    }
    
    int main()
    {
    	scanf("%d%s", &n, s + 1);
    	build(2333);
    	for (int i = 1; i <= n; i++) rk[sa[i]] = i;
    	for (int i = 1; i <= n; i++)
    	{
    		h[i] = h[i - 1] - (h[i - 1] > 0);
    		while (h[i] <= n && s[i + h[i]] == s[sa[rk[i] - 1] + h[i]]) h[i]++;
    		height[rk[i]] = h[i];
    	}
    }
    
  • 相关阅读:
    VI服务器
    LabVIEW编程技巧:网络通信中如何获取计算机名称、IP地址等信息
    Labview 局部变量
    TL431的几种常用用法
    s8550引脚图与电路图汇总分析
    齐二TK6916/20/26/32系列数控落地铣镗床简介8
    VBA Format函数 自定义格式中 0/#的区别
    [Excel VBA] Shape.Type属性名称及对应值列表
    如何另存(保存)不含宏
    我想一次性选择(或复制)工作簿中的多张表到另一工作簿
  • 原文地址:https://www.cnblogs.com/oier/p/10426239.html
Copyright © 2020-2023  润新知