zoukankan      html  css  js  c++  java
  • 后缀数据结构模板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];
    	}
    }
    
  • 相关阅读:
    菜鸟学存储:网络存储IP SAN与IB SAN
    读xml高手
    预先加载图片
    xred520
    最简单准确的硬盘整数分区设置操作方法
    Google 每天处理约 20000TB 的数据
    IE 8 无法正常使用网站后台编辑器问题
    常用的JS技术1
    adodb stream 使用说明
    [Tools] JDGUI(Java Decompiler)
  • 原文地址:https://www.cnblogs.com/oier/p/10426239.html
Copyright © 2011-2022 走看看