当前位置: 首页 > news >正文

sa后缀数组7.28

SA后缀数组

【模板】后缀数组

理解全在代码里

定义 :

$sa[i]$ 表示排名为i的后缀的开头位置

$rk[i]$ 表示以i为开头的后缀的排名(这里$i$均表示下标)

$tmp[i]$ 表示i对应的i-w的位置,为后面倍增两两合并准备

$height[i]$ 表示$lcp{({sa[i]},{sa[i - 1]})}$

$cnt[i]$ 计数排序的计数器

void get_sa(){int m = 255 ;for(int i = 1 ; i <= n ;++i)cnt[rnk[i] = s[i]]++; //初始化,给长度为1的赋值for(int i = 1 ; i <= m ;++i)cnt[i] += cnt[i - 1] ;//前缀和,计算for(int i = n ; i >= 1 ;--i)sa[cnt[rnk[i]]--] = i ; for(int w = 1 , t = 0 ; ; m = t , t = 0 , w <<= 1 ){//每次倍增长度for(int i = n - w + 1 ; i <= n ;++i)tmp[++t] = i;//如果 i + w > 0 就把他平行移到左边for(int i = 1 ; i <= n ;++i)if( sa[i] > w )tmp[++t] = sa[i] - w ;//否则直接赋值// for(int i = 1 ; i <= n ; i++){//     cout << i << " " << tmp[i] << " " << w << endl ;  // } // cout << endl ; for(int i = 0 ; i <= m ;++i)cnt[i] = 0 ;//重置计数器for(int i = 1 ; i <= n ;++i)cnt[rnk[tmp[i]]]++;//对第一关键字进行计数排序for(int i = 1 ; i <= m ;++i)cnt[i] += cnt[i - 1];//前缀和for(int i = n ; i >= 1 ;--i)sa[cnt[rnk[tmp[i]]]--]= tmp[i];//计算sa  swap(rnk , tmp) , t = 0 ;//这里应该是节省空间 直接使用把老的rnk赋给tmp , 用老的rnk更新新的rnkfor(int i = 1 ; i <= n ; i++)rnk[sa[i]] = (tmp[sa[i]] == tmp[sa[i - 1]] and tmp[sa[i] + w] == tmp[sa[i - 1] + w] ) ? t : ++t ; if( t == n )break ;//如果已经够了就不再排序了}
}
void getHeight(){for(int i = 1 , k = 0 ; i <= n ; ++i){if(k)--k;while(s[i + k] == s[sa[rnk[i] - 1] + k])k++;//直接暴力扩展height[rnk[i]] = k ;}
}

getHeight函数复杂度均摊$O(n)$

get_sa函数复杂度$O(n{logn})$

应用:

1.比较两个子串的大小关系

2.不同子串的数目

不同子串个数有 :$\{n*(n+1)/2 + sum_{i=1}height[i]}$ 种


文章转载自:

http://www.tdrn.cn/news/6553/
http://www.tdrn.cn/news/6552/
http://www.tdrn.cn/news/6551/
http://www.kefakeji.com/news/905.html

相关文章:

  • 哈希 kmp trie树
  • 多语言ppt改进
  • day30
  • redis的过期时间算法为什么要使用最小堆来实现时间轮,为什么不使用一个循环数组作为核心数据结构(ds)
  • 读心与芯:我们与机器人的无限未来07机器人的风险
  • 多项式 - 生成函数
  • 图灵奖和诺贝尔奖双料得主、AI教父Hinton:AI超越人类后,我们该怎么做
  • ICCV 2025 | 浙大等提出 SGCDet:自适应3D体素构建,重新定义多视图室内3D检测
  • 国产GPU芯片的天花板来啦!打破一切质疑,现场4K全高画质流畅跑黑猴!!!
  • 当AI教父都开始害怕AI
  • 共生伙伴:2025人工智能十大趋势|2025 WAIC报告重磅发布
  • 数据泄露激增与防护策略详解
  • 20250728
  • 白话Docker系列(一):用Web应用实例深入容器
  • 用 Vite + Cloudflare Pages 实现模块级独立打包与部署的静态 CDN 分发
  • [07.27学习笔记] Tokenizer - Luna
  • STM32F103C8T6芯片介绍(下) - LI,Yi
  • GRUB 设置安全启动
  • 【work记录】系统能力大赛数据库中的MVCC学习记录
  • FireStore如何查看空间占用情况?(未解决)
  • MIT6.s081_Lab8
  • 关于同源策略和跨域请求
  • Codeforces Round 1039 (Div. 2) 1 ~ D
  • 【转】[C#] 参数前加 in 的作用
  • 循环链表实现的队列
  • Codeforces Round 1039 (Div. 2)(A~E1)
  • 关于博客主题的一些思考
  • PG故障处理:PG_AUTO_FAILOVER自动切换失败的故障处理
  • Codeforces Round 1039 (Div. 2)
  • 21天