SA
Icefox_zhx
这个作者很懒,什么都没留下…
展开
-
SPOJ694&SPOJ705(后缀数组)
这俩题一样。。就后者数据范围大些。题目:给定一个字符串,求不相同的子串的个数。每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数。从1到n扫一遍,每一个suffix[sa[i]]的贡献为 n-sa[i]+1- height[i].(sa[i]的前缀个数-重复个数)#include #include #define N 50010int n,m,r原创 2017-07-17 16:26:55 · 471 阅读 · 0 评论 -
bzoj2946 [Poi2000]公共串(SA+二分答案 同poj3450)
求多个串的最长公共子串,一模一样,题解见这里原创 2017-08-24 19:52:07 · 429 阅读 · 0 评论 -
bzoj3238 [Ahoi2013]差异(SA+单调栈求所有区间最小值和)
我们很明显可以直接预处理出来T(i)+T(j)的总和,为n* (n-1)*(n+1)/2(推一下样例就可以了),然后主要问题是处理lcp的和。 这个地方我们可以直接在height数组上搞,我们可以发现,每一对(i,j)都对应了h数组上的一段区间、甚至是点!(当i,j两个子串rank相连的时候)那么同样的,每一个height数组上的一段区间(点)也对应我们要求的一个LCP。这样我们就不再关心是谁和谁原创 2017-08-24 21:59:47 · 770 阅读 · 2 评论 -
bzoj3172 [Tjoi2013]单词(SA+暴力,类似bzoj2754)
把所有单词连在一起,SA求出h数组,对于每一个单词看做一个询问,暴力往前往后扫,看有几个暴力统计即可。反正N才200原创 2017-08-24 20:33:03 · 350 阅读 · 0 评论 -
bzoj2119 股市的预测(SA+lcp)
走势相同,要进行差分,数的范围太大,还要离散化,然后就是求有多少子串样子是ABA,且B的长度已给定。枚举A的长度x,统计所有A的长度为x的答案。 我们以x对原串进行分块,每一块的第一个点设为关键点,我们发现对于一个ABA,第一个A一定覆盖且只覆盖一个关键点,我们枚举关键点i,i和i+mm+x往左往右匹配长度l和r(r包括关键点),如果l+r>=L那么这个地方就有l+r-x+1个满足的子串。因为要避原创 2017-08-15 00:01:35 · 490 阅读 · 0 评论 -
bzoj3277&&bzoj3473 串(SA+二分+lcp)
首先老套路,我们把所有串接在一起,用分隔符隔开,做SA,求出h数组,并用st表求lcp。然后分析题目,我们对于每个串分别统计答案。假定我们正在做第i个串,在总串中从sta开始,到ed结束。则我们要求的就是每个后缀a[sta…ed],a[sta+1…ed]…a[ed]对答案的贡献和。假设我们在求a[j…ed]这个后缀的贡献。则他的贡献就是有几个前缀出现在k个及以上不同串中,显然如果a[j..j+len原创 2017-08-26 14:22:20 · 494 阅读 · 0 评论 -
bzoj3676 [Apio2014]回文串(manacher+SA+二分+lcp)
manacher板子戳这里 我们用manacher枚举回文串,用SA求这个串的出现次数。(利用h数组二分求最大包含区间[l…r],则出现次数为r-l+1)类似这道题。不错的好题。。。原创 2017-08-26 15:58:09 · 309 阅读 · 0 评论 -
bzoj3796 Mushroom追妹纸(SA+二分答案+kmp)
把s1和s2接在一起,求最长公共子串。二分答案就好了。。。此题就多一个判断,要求s3不能出现在公共子串里,那我们就预处理一下,用kmp求出s3在s2中出现的位置,处理成L数组,即可O(1)判断。原创 2017-08-26 16:58:07 · 523 阅读 · 0 评论 -
CF204E Little Elephant and Strings(同bzoj3277)
原题,还写了好久orz。传送门原创 2017-10-07 14:11:41 · 547 阅读 · 0 评论 -
bzoj5137 [Usaco2017 Dec]Standing Out from the Herd(后缀数组)
我们首先把所有串接在一起,用分隔符隔开,跑一遍sa,求出h数组。然后我们考虑每个串如何算贡献,一个串的所有后缀一定是在rank数组上的若干连续段,对于每一个连续段[l,r],我们首先计算出本质不同的子串个数,类似这题。然后考虑因出现在其他串而要减少的贡献,就是lcp(l-1,l)+lcp(r,r+1)-lcp(l-1,r+1),注意去重。原创 2018-02-12 23:28:15 · 491 阅读 · 1 评论 -
bzoj4278 [ONTAK2015]Tasowanie(贪心+后缀数组)
感觉以前听ly神犇说过吧。就是贪心地选择后缀排名更小的。 证明可以戳这里看看:传送门原创 2018-02-22 19:59:11 · 291 阅读 · 0 评论 -
bzoj5159 [Tjoi2014]电影评分(splay+后缀平衡树)
按道理应该是一定会挂精度的,正解应该是后缀平衡树来比较两个数的小数部分的大小。但是数据水,直接long double是可以水过的【逃】。正解待更新。。tips:注意是最早的而不是标号最小的,我们还要枚举一下题意,发现他说的是如果评分相同就按出现时间给排名【逃】。3.13upd:更新正解 我们现在的问题是如何比较两个实数的大小。我们可以直接比较整数部分, 注意到小数部分可以看成一个二进制...原创 2018-03-12 23:04:44 · 449 阅读 · 0 评论 -
bzoj4556 [Tjoi2016&Heoi2016]字符串(SA+二分答案+线段树)
给定一个串S,每次询问S[a..b]中的子串与S[c..d]的lcp的最大值。子串其实就可以当做后缀。那么每次就是求后缀[a..b]与c的lcp最大值。我们考虑二分答案ans,用SA处理出h数组,那么就可以再二分答案得到c向前向后拓展的最远距离。即[l..r]中的串与c的lcp都>=ans,然后我们就要看这些串中是否有合法的,即是否存在一个串的下标在[a…b-ans+1]之间。这怎么判断呢?我们可以原创 2018-03-29 21:24:37 · 314 阅读 · 0 评论 -
bzoj3998 [TJOI2015]弦论(SA/SAM)
求第k小子串。如果t=0,直接拿sa线性搞即可。如果t=1,我复杂度就炸了。。。然而本机和luogu都跑了过去(可见数据之水,逃)。正解大概是SAM,待更新。3.24upd:蒟蒻我终于看懂了SAM的板子orz 顾名思义,SAM就是能识别所有后缀的自动机。我们有一个朴素的构建SAM的想法:把每一个后缀都插到Trie里去!但是这样是O(n^2)的,无论时间还是空间都会炸。怎么办呢?我们要压缩状态,一些原创 2018-03-22 12:49:07 · 304 阅读 · 0 评论 -
bzoj4892 [Tjoi2017]dna(SAM/SA/二分答案+Hash)
在后缀自动机上跑一跑就好啦。O(n)O(n)O(n) SA题解:portalO(nlogn)O(nlogn)O(nlogn) upd:还可以二分答案+Hash来求lcp哟。O(nlogn)O(nlogn)O(nlogn)SAM#include <cstdio>#include <cstring>#include <algorithm>#incl...原创 2018-03-26 15:57:50 · 432 阅读 · 0 评论 -
bzoj5073 [Lydsy1710月赛]小A的咒语(SA+lcp+dp+贪心)
考虑dp,f[i][j]表示A串前i字符分成j段能匹配的最大B串前缀长度。 那么如果i+1不选,转移到f[i+1][j]如果i+1选,则我们可以贪心的尽量多匹配一些,即匹配t=lcp(i+1,f[i][j]+1)个,转移到f[i+t][j+1]我们SA+RMQ预处理一下,O(1)查询lcp即可。复杂度O(T(nk+nlogn))O(T(nk+nlogn)) 注意多组数据的一些细节,比如rk要清零原创 2018-04-27 22:01:05 · 315 阅读 · 0 评论 -
bzoj4310 跳蚤(SA+二分答案+贪心)
原题描述有误,应该是把原串分成最多k个子串,然后在每个子串中挑出字典序最大的子串,使得这些串中最大的字典序最小。我们二分答案是第K小子串,用SA搞出这个串的位置,然后去贪心判定是否可行,即是否存在一种划分使得所有子串都小于等于这个串。如何贪心判定呢?首先如果有一个s[i]>s[ansl],则肯定怎么划分都不行。不然的话我们从后往前判断,如果当前串的大小超过了答案串,则必须砍一刀,我们贪心的砍在最前面原创 2018-04-28 12:43:13 · 301 阅读 · 0 评论 -
bzoj2534 Uva10829L-gap字符串(SA+lcp同bzoj2119)
求形如ABA的子串个数,同bzoj2119,题解看这里 tips:没说全是小写字母你就别换成int了。。。无谓的WA三发#include原创 2017-08-24 17:00:16 · 376 阅读 · 0 评论 -
bzoj2754 [SCOI2012]喵星球上的点名(后缀数组+暴力)
把所有串接在一起,打上分割符。SA求出h数组。然后就暴力。。每一个询问串往后往前扫h大于询问串长度的。然后暴力统计答案。。。复杂度很玄学。 tips:这题数据范围太大。。注意越界问题的细节。。原创 2017-08-24 18:00:18 · 657 阅读 · 0 评论 -
bzoj3230 相似子串(SA+lcp+二分)
首先用后缀数组处理出h数组。因为要问子串的排名,所以我们再记一个数组num[i],表示前i个后缀有几个本质不同的子串。然后我们用二分查找就可以找到排序后的第i个子串是谁了。然后就是求一下lcp了。。还有反过来的lcp。。算清角标就好了。。还有很坑的一点:可能有超过int范围个实质不同的字串=,=.#include <cstdio>#include <cstring>#include <algor原创 2017-08-03 16:20:00 · 436 阅读 · 0 评论 -
bzoj1031[JSOI2007]字符加密Cipher(拆环变链,利用sa数组)
挺裸的一道后缀数组。。注意是环,把他在后面复制一遍再做就好了。。#include #include #define N 200005char s[N];int n,rank[N<<1],st[256],rank1[N],count[N],sa[N],tmp[N];int main(){// freopen("a.in","r",stdin); scanf("%s",s+1原创 2017-07-17 16:32:14 · 365 阅读 · 0 评论 -
bzoj1717(poj3261) [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组,二分答案)
给定一长度为N的数字序列,找出在序列中重复出现了至少K次的最长子串。二分答案。利用h数组判断即可。按h分组,连续大于等于x的分在一组,他们肯定有相同的前缀,统计次数即可。#include #include #include #define N 20005int n,m,a[N],aa[N];int rank[N<<1],count[N],rank1[N],sa[N],t原创 2017-07-17 16:35:51 · 383 阅读 · 0 评论 -
bzoj1692 [Usaco2007 Dec]队列变换(后缀数组)
DescriptionFJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”。在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席前依次走过。 今年,竞赛委员会在接受队伍报名时,采用了一种新的登记规则:他们把所有队伍中奶牛名字的首字母取出,按它们对应奶牛在队伍中的次序排成一列(比如说,如果FJ带去的奶牛依次为Bessie、Sylv原创 2017-07-17 16:45:39 · 334 阅读 · 0 评论 -
ural1297Palindrome (后缀数组+lcp)
求最长回文子串,且此题要求最先出现,SA+lcp解决。原想法:首先反转,拼接原串与反转串,然后求两者的最长公共前缀,唯一注意的是如果有多组要输出最先出现那一组。原想法是错误的。反例:zzzdzaadzzz。可以自己摸索下,实在不行,来这位大神博客下拜读一下也是可以的。传送门正解:首先要在本身与镜像之间插入一个特殊的,不可能出现的字符。我们枚举每一个原始字符串中的字符以它为中心(原创 2017-07-17 21:43:15 · 264 阅读 · 0 评论 -
SPOJ687 Repeats (后缀数组+lcp)
求循环节个数最大的子串的循环节个数。很绕吧。。基本和poj3693相同,此题要简单些。因为我先看了hzw的poj3693的题解。。所以我也写的是反过来做一遍求l。先入为主了呢。。网上还有很多人写的其实不需要反过来做一遍去求l,大家可以去借鉴下。。我觉得时间上差不多。。所以就懒得改了呢。。(思路有问题还是参考3693吧。。)#include #include #define N 50010原创 2017-07-18 18:48:11 · 354 阅读 · 0 评论 -
bzoj4199[luoguP2178]品酒大会[noi2015] (后缀数组+并查集)
bzoj上居然没题面。。可怕。洛谷上都有。首先,r相似其实就是lcp为r。那么就有个显然的做法。每次枚举lcp,按h分组,一组内有cnt个,则答案就是在cnt个数中选两个,C(cnt 2)。符号不会打,意思到了就好。。然后最大值。。想想怎么维护就好了。直接看代码吧。然后就可以拿到50分。而正解是这样的:r相似是不是至少有r+1相似个?那么r+1相似有多少个是不是跟r相似没啥关系??所以我们原创 2017-07-18 22:59:15 · 397 阅读 · 0 评论 -
bzoj4829 [TJOI2017]dna(后缀数组)
luogu3763有题面可以去看的说。。大牛分站开o2优化了(没错我就是这样才过的。)后缀数组处理一下lcp,然后枚举三次就好了。bzoj上我的总是T。嗯,一定是姿势不对。。不过我看神犇们都是用SAM写的,贼快。我也要去学习一下。。#include #include #define N 200005char s[N];int tst,n,len1,len2,m,st[N][19],lo原创 2017-07-23 13:20:00 · 549 阅读 · 0 评论 -
poj3080 Blue Jeans(后缀数组+二分答案)
和poj3450一模一样。。双倍经验,嗯,很好。#include #include #define N 10000int mm,m,n,ansl=0,a[N],id[N],tst;int rank[N<<1],rank1[N],tmp[N],count[N],sa[N],h[N];inline int min(int x,int y){return x<y?x:y;}inline原创 2017-07-19 15:59:53 · 343 阅读 · 0 评论 -
poj3693(后缀数组+lcp+rmq)
求循环节个数最大的子串。先穷举长度L,然后求长度为L 的子串最多能连续出现几次。首先连续出现1 次是肯定可以的,所以这里只考虑至少2 次的情况。假设在原字符串中连续出现2 次,记这个子字符串为S,那么S 肯定包括了字符r[0], r[L], r[L*2],r[L*3], ……中的某相邻的两个。所以只须看字符r[L*i]和r[L*(i+1)]往前和往后各能匹配到多远,记这个总长度为K,那原创 2017-07-18 18:56:12 · 661 阅读 · 0 评论 -
poj3294 Life Forms(后缀数组+二分答案)
求在≥k个串中出现过的最长子串.还是先都连起来,用特殊字符隔开,然后二分答案,按h分组,在一组内统计出现过的子串,满足条件就更新,注意可能有多个子串满足条件,按照顺序存下来就好了。大坑点见注释。(有人就拿char过了,很神。)#include #include #define N 102000int s[N];bool blank=0,vis[110];int belong[N],n原创 2017-07-17 21:38:55 · 382 阅读 · 0 评论 -
poj1743 Musical Theme(后缀数组+二分答案)
都做个差值,就解决了转调问题,然后就是求最长不重叠重复子串。二分答案即可。判断不重叠:按h分组后,记录一组中的最小id--mn和最大id--mx,if(mx-mn>=x)即存在不重叠的。#include #include #define N 20005inline int min(int x,int y){return x<y?x:y;}inline int max(int x,i原创 2017-07-17 21:33:06 · 327 阅读 · 0 评论 -
poj3450 Corporate Identity(后缀数组+二分答案)
题意:求多个串的最长公共子串把所有串都接在一起。。用特殊字符隔开。然后和两个串的一样,二分答案,每次判断这个长度是否可行。(分组,一组中出现在所有串中即满足)我以前写的SA太弱了。。还TLE了。。改进了一下下。#include #include #define N 805000int mm,m,n,ansl=0,a[N],id[N];int rank[N<<1],rank1原创 2017-07-17 21:27:33 · 477 阅读 · 0 评论 -
poj2774 Long Long Message(后缀数组)
很简单的后缀数组,求两个串的最长公共子串。把这两个串,用特殊字符隔开连在一起,更新合法的最大公共前缀即可。原创 2017-07-17 15:15:08 · 310 阅读 · 0 评论 -
poj3415Common Substrings(后缀数组+单调栈)
题目大意:给两个字符串,求所有满足 长度大于等于k的公共子串 的对数。思路:基本的,计算A 的所有后缀和B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k 的部分全部加起来。(显然会TLE到死),所以我们把这两个串连起来(中间用特殊字符隔开),根据h数组进行分组,保证一组内字符串之间lcp都是大于等于k的。接下来的工作便是快速的统计每组中后缀之间的最长公共前缀之和。扫描一遍原创 2017-07-17 14:36:08 · 355 阅读 · 0 评论 -
bzoj4698 [Sdoi2008] Sandy的卡片(后缀数组+二分答案)
差分,就像poj1743那样,多个串的最长公共子串,就像poj3450那样。然后就过了。据说kmp也可以写过这道题。。。各位可以试试。#include #include #define N 1100000int n=0,m=4000,tot,belong[N],s[N],ans=0;int sa[N],rank[N<<1],rank1[N],tmp[N],count[N],h[N];原创 2017-07-24 17:44:12 · 355 阅读 · 0 评论 -
bzoj2251 [2010Beijing WC]外星联络(后缀数组+暴力)
求所有出现次数大于1的字串。。用后缀数组处理出h数组,每个子串第一次出现时,往后扫,看重复了几次。n=3000,暴力即可。原创 2017-08-03 12:58:59 · 420 阅读 · 0 评论 -
bzoj4650 [Noi2016]优秀的拆分(计数+SA)
好久没写SA了的赶脚qaq 考试时写了95分的O(n2)O(n2)O(n^2)暴力hash我们考虑枚举中间分割点i,以i结尾的AA串个数*以i+1开头的AA串个数就是对答案的贡献。于是我们只需要处理出f[i],以i结尾的AA串个数 g[i],以i开头的AA串个数这两个数组。我们考虑枚举AA串的半长度len,每隔len个设一个关键点,那么一个合法的长度为len的AA串一定包含了恰好两个...原创 2018-06-27 23:07:09 · 203 阅读 · 0 评论