题目链接 \(Description\) 给定SA数组,求满足SA[]的一个原字符串(每个字符为小写字母),无解输出-1. \(Solution\) 假设我们现在有suf(SA[j]),要构造suf(SA[i]) (要满足i>j) 考虑后缀的比较方式,先比较第一位,再比较suf(SA[i]+1)与suf(SA[j]+1) 若suf(SA[i]+1)>suf(SA[j]+1),则两字符串第一位可以相同:否则一定要在第一位满足suf(SA[i])>suf(SA[j]) 按照这种方式构造,就能…
题面 Description 话说练习后缀数组时,小C 刷遍 poj 后缀数组题, 各类字符串题闻之丧胆.就在准备对敌方武将发出连环杀时,对方一记无中生有,又一招顺 手牵羊,小C 程序中的原字符数组就被牵走了.幸运的是,小C 早已经求出了 SA[],为了 能东山再起,迅速 A 掉此题,他希望各位忠臣们能帮忙求出一组原字符数组的可行方案.已 知原字符数组由小写拉丁字母组成.且小C的SA[]也是有可能求错的, 原数组可能不存在. Input 输入文件只有一行且为用空格隔开的一个正整数 N. 接下来一…
题目大意 给定后缀数组sa,要求构造出满足sa数组的字符串.或输出无解\(n\leq 5*10^5\) 题解 我们按照字典序来考虑每个后缀 对于\(Suffix(sa[i])\)和\(Suffix(sa[i-1])\) 我们一定知道\(Suffix(sa[i-1])<Suffix(sa[i])\). 如果我们有\(Suffix(sa[i-1]+1)<Suffix(sa[i]+1)\) 那么\(sa[i]\)和\(sa[i-1]\)两个位置上的字符相等时也满足条件 那么从贪心的角度来讲我们就让\…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4319 如果字符集有 5e5 那么大的话,挨个填上去就行了.但只有26个字符,所以要贪心地尽量填和上一次一样的字符. 按 sa[ ] 的顺序从小到大填字符,判断这个位置 x 能否填上一次在 y 填的字符的条件就是 rk[ x+1 ] > rk[ y+1 ]. 因为 x 的字典序比 y 大,而 x 位置要填和 y 一样的字符,所以 x 的后面应该比 y 大.发现后面部分也是两个后缀,所以利用“…
如果字符集无限大的话直接按照 $sa$ 的顺序依次填即可. 由于字符集非常小,所以要尽量填相同的字符. 我们知道 $sa$ 数组,也就知道了 $rank$ 数组. 那么考虑添加排名为 $i$ 的字符: 如果 $rank[sa[i-1]+1]>rank[sa[i]+1]$,说明 $sa[i]$ 的字典序必须比 $sa[i-1]$ 的字典序大,新建字符. 否则,就不用新建字符. 这么做下去即可. code: #include <bits/stdc++.h> #define N 503000…
BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想到对后缀求height,也就是用 后缀数组+单调栈 维护一段\(height\)相同的区间,单调栈中的\(height\)递增,顺便维护区间最小值(有负数).最大值.元素个数. (然后我就不会写了...) 每次弹出区间时,计算该区间右端点和后面的点与该区间内的点的答案(该区间内的点作为右端点的答案已…
倍增算法 基本定义子串:字符串 S 的子串 r[i..j],i≤j,表示 r 串中从 i 到 j 这一段也就是顺次排列 r[i],r[i+1],...,r[j]形成的字符串. 后缀:后缀是指从某个位置 i 开始到整个串末尾结束的一个特殊子串. 字串 r 的 从 第 i 个 字 符 开 始 的 后 缀 表 示 为 Suffix(i) , 也 就 是Suffix(i)=r[i..len(r)]. 后缀数组:后缀数组 SA 是一个一维数组,它保存 1..n 的某个排列 SA[1],SA[2],……,S…
这题可以用回文自动机来做,但是我并没有学,于是用Manacher+SA的做法O(nlogn)水过 首先,看到回文串就能想到用Manacher 同样还是要利用Manacher能不重复不遗漏地枚举每个回文子串的性质 只是不重复不遗漏还不够,我们还要统计出现次数 每个子串一定是一个后缀的前缀,于是可以用后缀数组 用后缀数组求出height数组之后,对于在Manacher过程中枚举到的每个长度为k的回文串,可以在height数组中二分,用O(logn)的时间求出这个子串的出现次数 BZOJ和COGS上有…
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 nn 杯鸡尾酒.这 nn 杯鸡尾酒排成一行,其中第 ii 杯酒 (1≤i≤n1≤i≤n) 被贴上了一个标签 sisi,每个标签都是 2626 个小写英文字母之一.设 Str(l,r)Str(l,r)…
题目大意: 给定n个字符串连成了一篇文章,问每个字符串在这篇文章中出现的次数,可重复覆盖 这里ac自动机和后缀数组都可以做 当然后缀数组很容易就解决,但是相对时间消耗高 这里就只讲ac自动机了 将每个字符串放入ac自动机中,这里需要记录到达每个ac自动机上的节点出现这个状态有多少次 而我们添加字符串进入的时候,应该是把经过的每个节点的val都++,说明这个字符串多出现了一次这个值 然后因为自己用字符串在ac自动机上走肯定是到达离root最近的点,也就是说有很多的点会不断通过fail指针指向他,而…
求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N)) ----------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm>   using namespace std;…
二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) --------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<cctype>   using namespace std;   typedef long l…
题目链接 环可以拆成链:对字符串排序能想到后缀数组. 完了.输出时忽略长度不足n的串,输出s[sa[i]+n-1],即排名为i的字符串的末尾. //4140kb 744ms #include <cstdio> #include <cstring> #include <algorithm> const int N=2e5+5; int n,tm[N],sa[N],rk[N],sa2[N]; char s[N]; void Get_SA() { int m=130,*x=r…
题目大意 给定\(k\)和长度\(\le10^5\)的串S 把串分成不超过\(k\)个子串,然后对于每个子串\(s\),他会从\(s\)的所有子串中选择字典序最大的那一个,并在选出来的\(k\)个子串中再选择字典序最大的那一个.他称其为"魔力串". 输出最小的魔力串 分析 最大值最小\(\Rightarrow\)二分+判定性问题 考虑对于选出来的\(k\)个子串\(s\),\(s\)中最大子串一定是\(s\)的某个后缀 做法 我们在所有本质不同字符串中按找字典序进行二分 得到一段字符…
题目描述 话说练习后缀数组时,小C 刷遍 poj 后缀数组题, 各类字符串题闻之丧胆.就在准备对敌方武将发出连环杀时,对方一记无中生有,又一招顺手牵羊,小C 程序中的原字符数组就被牵走了.幸运的是,小C 早已经求出了 SA[],为了能东山再起,迅速 A 掉此题,他希望各位忠臣们能帮忙求出一组原字符数组的可行方案.已知原字符数组由小写拉丁字母组成.且小C的SA[]也是有可能求错的, 原数组可能不存在.  输入 输入文件只有一行且为用空格隔开的一个正整数 N.  接下来一行有 N 个数,为 1~N…
Solution 1: 后缀数组暴力大法好 #include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i)…
后缀数组 顾名思义.SuffixArray(下面有时简称SA) 和字符串的后缀有关. 后缀:字符串中某个位置一直到结尾的子串.(SA中讨论包含了原串和空串).所以共同拥有len+1个后缀. 后缀数组: 字符串的全部后缀组成的按字典序从小到大排好的数组.因为SA中记录的都是字符串的后缀,所以SA仅仅须要记录其表示的后缀的起始位置. 因为比較字典序是O(n)的,所以暴力算法的复杂度将是O(n^2logn).通过一些算法能够降到线性复杂度.这里先介绍一种简单的O(nlognlogn)的算法. 该算法的…
题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个串的长度>=x, 但据说有一种高端做法是把二分换成单调队列,能减少常数,可惜我并没有看懂...... 原题好像是哈希的骚操作,但网上的题解好像都是后缀数组...... 比上一道男人八题简单多了,我原来的错代码竟然卡过去了70分.. #include <cstdio> #include <…
Tasowanie bzoj-4278 ONTAK-2015 题目大意:给定两个字符串,求两个字符串二路归并之后生成的字典序最小的字符串是什么. 注释:$1\le len_1,len_2\le 2\cdot 10^5$. 想法: 和队列变换比较像啊. 我们将两个串接在一起然后建立后缀数组即可. 紧接着像那道题一样,在$sa$上弄两个指针贪心地移动即可. Code: #include <iostream> #include <cstdio> #include <cstring&…
队列变换 bzoj-1692 Usaco-2007 Dec 题目大意:给定一个长度为$n$的字符串.每次从头或尾取出一个字符加到另一个字符串里.要求变换后生成的字符串字典序最小,求字典序最小的字符串. 注释:$1\le n\le 3\cdot 10^4$. 想法: 考虑暴力怎么做: 每次把当前字符串左右较小的取出来.如果一样就对着往中间枚举,直到不一样为止. 这样时间复杂度为$O(n^2)$,全是一样的字符即可卡掉. 显然上述过程我们就是比较正反两个字符串谁的字典序更小对吧. 那么我们把原串翻转…
原文链接http://www.cnblogs.com/zhouzhendong/p/9016336.html 题目传送门 - BZOJ4319 题意 给出一个$1,2,\cdots,n$的排列,第$i$项表示$SA[i]$. 让你构造一个只含有小写字母的字符串,使其$SA$数组为输入的值.或者输出无解. $n\leq 5\times  10^5$ 题解 首先,我们预处理出所有的$rank[i]$. 然后我们枚举$i$. 考虑给第$SA[i]$个位置插入字符. 给$SA[i]$处插入的字符必然不小…
根据height数组的定义,和当前后缀串i最长的相同串的长度就是max(height[i],height[i+1]),这个后缀贡献的最短不同串长度就是len=max(height[i],height[i+1]) 考虑这个贡献的范围,对于i~i+len,贡献是len,对于w=i+len+1~n可以更新w-len+1,也就是这长为len的串再向右延伸,可以证明这也是不重子串 这两个东西用两个线段树维护,w-len+1这个直接把-len+1打在线段树上,查询的时候再加回w即可 #include<ios…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4556 本来只要查 ht[ ] 数组上的前驱和后继就行,但有长度的限制.可以二分答案解决!然后用主席树查区间内的 ht[ ] 的前驱和后继即可.(主席树弄对 rk 的权值线段树) 在主席树上走的复杂度应该不会比二分然后查看主席树的 log2 更差吧. #include<cstdio> #include<cstring> #include<algorithm> usi…
题目大意 在结尾动态插入字符,每次插入结束后输出当前串中本质不同的字串个数 题解 注意一开始是空串,然后我们我们可以打表观察规律 我们发现一直在开头插入字符和一直在结尾插入字符得到的答案是一样的 所以我们从开头插入字符 那么每次我们相于插入了一个后缀 这样就多了n-sa[i]个前缀 但是这些前缀中有重复的 所以我们要在已经插入的后缀中找出与之最长的lcp长度 减去这个长度就是我们得到的不同的字串个数了 由于求lcp时是对height一直取min 所以我们找最长的lcp是只需要找所有已经计算的了后…
很容易想到只考虑后缀长度必须为\(max(height[rk[i]],height[rk[i]+1])+1\)(即\([i,i+x-1]\)代表的串只出现过一次)然后我正着做一遍反着做一遍,再取一个\(min\)最后挂了... 设\(x=max(height[rk[i]],height[rk[i]+1])+1\)我们考虑\(i\)的贡献,会给区间\([i,i+x-1]\)一个贡献x ,设\(r=i+x-1\)然后会给r+1一个贡献x+1就是(r+1)-i+1,接着是r+2的贡献(r+2)-i+1…
2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 331  Solved: 153[Submit][Status][Discuss] Description 墨墨的妈妈热爱炒股,她要求墨墨为她编写一个软件,预测某只股票未来的走势.股票折线图是研究股票的必备工具,它通过一张时间与股票的价位的函数图像清晰地展示了股票的走势情况.经过长时间的观测,墨墨发现很多股票都有如下的规律:之前的走势很可能在短时间内重现!如图可以看到这只股票A…
题目大意:求一个字符串中形如$ABA$的串的数量,其中$B$的长度是给定的 有点像[NOI2016]优秀的拆分这道题 先对序列打差分,然后离散,再正反跑$SA$,跑出$st$表 进入正题 $ABA$串有一个神奇的性质 令$A$串长度是$x$ 如果我们选取了一个位置$i$,再选取一个位置$i+x+m$ 用预处理的$st$表,求出经过它们的,最长的相同子串的起始位置$s$和结束位置$e$ 合法的$ABA$串似乎在$[s,e]$之间滑动 有了这个性质,我们再外层枚举长度$x$,在序列中找出一些相隔为$…
The Revenge of the Princess’ Knight Problem Description There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is jus…
题目链接 首先这种题一看就是dp. 设\(dp[i][j]\)表示\(A\)序列中到\(i\)位之前,取了\(j\)段,在\(B\)中的最长的长度. 转移也比较简单 \[ dp[i][j] \to dp[i+1][j] \quad \text{不选} \\ dp[i][j] \to dp[i+k][j+1] \quad a[i+1..i+k]=b[dp[i][j]..dp[i][j]+k] \] 但是这样做的复杂度肯定不行. 发现有一个贪心的思路,因为既然我这里已经占用了一次次数了,那么肯定要尽…
参考: Suffix array - Wiki 后缀数组(suffix array)详解 6.3   Suffix Arrays - 算法红宝书 Suffix Array 后缀数组 基本概念 应用:字符串处理.生物信息序列处理 后缀:学过英语的都知道什么叫后缀,就是从某个位置开始到字符串结尾的特殊子串,记住 Suffix(i)=S[i...len(S)-1],i就是后缀起始位置 后缀数组:就是将后缀排序好后放到一个一维数组里,SA[i]存放排名第i大的后缀首字符下标,并且保证 Suffix(SA…