Warning: session_start(): open(/tmp/sess_e7185182ca1ed1ca079fbcb3c58cc2a8, O_RDWR) failed: No space left on device (28) in /data/wiki/inc/init.php on line 239

Warning: session_start(): Failed to read session data: files (path: ) in /data/wiki/inc/init.php on line 239

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/auth.php on line 430
Writing /data/wiki/data/cache/d/de2edb2fcb553ea79b79c722a4e13dbc.captchaip failed

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/actions.php on line 38

Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/lib/tpl/dokuwiki/main.php on line 12
2020-2021:teams:legal_string:后缀数组_lgwza [CVBB ACM Team]

用户工具

站点工具


2020-2021:teams:legal_string:后缀数组_lgwza

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
2020-2021:teams:legal_string:后缀数组_lgwza [2020/07/24 16:10]
lgwza
2020-2021:teams:legal_string:后缀数组_lgwza [2020/07/24 16:17] (当前版本)
lgwza [一些常数优化]
行 43: 行 43:
 参考代码: 参考代码:
  
 +<​hidden>​
 <code cpp> <code cpp>
 #include <​algorithm>​ #include <​algorithm>​
行 86: 行 87:
 } }
 </​code>​ </​code>​
 +</​hidden>​
 ==== $O(n\log n)$ 做法 ==== ==== $O(n\log n)$ 做法 ====
  
行 97: 行 98:
 参考代码: 参考代码:
  
 +<​hidden>​
 <code cpp> <code cpp>
 #include <​algorithm>​ #include <​algorithm>​
行 147: 行 149:
 } }
 </​code>​ </​code>​
 +</​hidden>​
 ==== 一些常数优化 ==== ==== 一些常数优化 ====
  
行 158: 行 161:
  
 实际上,像这样就可以了: 实际上,像这样就可以了:
 +
  
 <code cpp> <code cpp>
行 183: 行 187:
 参考代码: 参考代码:
  
 +<​hidden>​
 <code cpp> <code cpp>
 #include <​algorithm>​ #include <​algorithm>​
行 228: 行 233:
 } }
 </​code>​ </​code>​
 +</​hidden>​
 ==== $O(n)$ 做法 ==== ==== $O(n)$ 做法 ====
  
行 240: 行 246:
 === DC3 === === DC3 ===
  
-可以参考 ​[[[https://​wenku.baidu.com/​view/​5b886b1ea76e58fafab00374.html|2009]后缀数组——处理字符串的有力工具 by. 罗穗骞]]。+可以参考 [[https://​wenku.baidu.com/​view/​5b886b1ea76e58fafab00374.html|2009 后缀数组——处理字符串的有力工具 by. 罗穗骞]]。
  
 ===== 后缀数组的应用 ===== ===== 后缀数组的应用 =====
行 267: 行 273:
 参考代码: 参考代码:
  
 +<​hidden>​
 <code cpp> <code cpp>
 #include <​cctype>​ #include <​cctype>​
行 322: 行 329:
 } }
 </​code>​ </​code>​
 +</​hidden>​
 +
 +===== height 数组 =====
 +
 +==== LCP(最长公共前缀) ====
 +
 +两个字符串 $S$ 和 $T$ 的 LCP 就是最大的 $x$ ($x\le\min(|S|,​|T|)$) 使得 $S_i=T_i(\forall1\le i\le x)$。
 +
 +下文中以 $lcp(i,j)$ 表示后缀 $i$ 和后缀 $j$ 的最长公共前缀(的长度)。
 +
 +==== height 数组的定义 ====
 +
 +$height[i]=lcp(sa[i],​sa[i-1])$,即第 $i$ 名的后缀与它前一名的后缀的最长公共前缀。
 +
 +$height[1]$ 可以视作 $0$。
 +
 +==== O(n) 求 height 数组需要的一个引理 ====
 +
 +$height[rk[i]]\ge height[rk[i-1]]-1$
 +
 +证明:
 +
 +
 +
 +==== O(n) 求 height 数组的代码实现 ====
 +
 +利用上面这个引理暴力求即可:
 +
 +<code cpp>
 +for (i = 1, k = 0; i <= n; ++i) {
 +  if (k) --k;
 +  while (s[i + k] == s[sa[rk[i] - 1] + k]) ++k;
 +  ht[rk[i]] = k;  // height太长了缩写为ht
 +}
 +</​code>​
 +$k$ 不会超过 $n$,最多减 $n$ 次,所以最多加 $2n$ 次,总复杂度就是 $O(n)$。
 +
 +未完待续
 +
 +===== 参考链接 =====
 +
 +[[https://​oi-wiki.org/​string/​sa/​|参考链接]]
2020-2021/teams/legal_string/后缀数组_lgwza.1595578202.txt.gz · 最后更改: 2020/07/24 16:10 由 lgwza