当时后缀数组没有好好学...各种应用都没学,这两天好好补,要把罗神的论文好好研究一遍...其实后缀数组真的好神奇!!特别是那个萌萌的height数组! 今天终于能有两节完整的晚自修了QAQ...明晚还要去一彩,估计心态又没法像今晚那么稳定了...争取这星期能去复习AC自动机吧... 嗯,忽然发现,自己一个晚上只看了6个例子?!这速度...不吐槽了,最近也不把自己逼太紧,要每天有点进步就好...忙新晚的伤不起…
感觉后缀数组很难学的说= = 不过总算是啃下来了 首先 我们需要理解一下倍增法构造的原理 设原串的长度为n 对于每个子串 我们将它用'\0'补成长度为2^k的串(2^k-1<n<=2^k) 比如串aba的子串就有 aba'\0'    ba'\0''\0'  a'\0''\0''\0' 每次操作我们可以排出所有长度为 2^x的子串的大小 比如串aba的排序过程 第一遍 a                   a             b 第二遍 a'\0'             ab  …
给定一个整数数组,除了某个元素外其余元素均出现两次.请找出这个只出现一次的元素.备注:你的算法应该是一个线性时间复杂度. 你可以不用额外空间来实现它吗? 详见:https://leetcode.com/problems/single-number/description/ Java实现: class Solution { public int singleNumber(int[] nums) { int n=nums.length; if(n==0||nums==null){ return In…
Given an array of integers, every element appears twice except for one. Find that single one. class Solution { public: int singleNumber(vector<int>& nums) { int size=nums.size(); ||nums.empty()) ; ; ;i<size;++i) res^=nums[i]; return res; } };…
Boring counting Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出现了两次(无重叠)的子串的种类数. analyse: 后缀数组中height数组的运用,一般这个数组用得很少. 总体思路:分组统计的思想:将相同前缀的后缀分在一个组,然后对于1到len/2的每一个固定长度进行统计ans. 首先我们先求一遍后缀数组,并把height数组求出来.height数组代表的含…
http://acm.hdu.edu.cn/showproblem.php?pid=5769 题意:在S串中找出X串出现的不同子串的数目? 其中1 <= |S| < $10^5$ 官方题解: 处理出后缀数组中的sa[]数组和height[]数组.在不考虑包含字符X的情况下,不同子串的个数为 如果要求字符X,只需要记录距离sa[i]最近的字符X的位置(用nxt[sa[i]]表示)即可,个数 理解:后缀数组height[i]就是sa[i]与sa[i-1]的LCP,在后缀数组中求解全部的不同子串(之…
题目链接 题意:给定n个数字,求超过5个数字的,最长的,变化相同的,不相交的重复子串 分析:男人8题中的一题!数列相邻两项做差,形成新数列,即求数列中的最长重复子串(不可相交). 后缀数组+二分答案.假如二分得到答案L,如何知道它是可行的呢? 因为对于排序后的后缀,Lcp ( Suffix ( List [ i ] ) , Suffix ( List [ i - 1 ] ) ) 是所有与Suffix ( List [ i ] )的LCP值中最大的一个. 因为 Height [ i ] 表示的是排…
题目描述: 找出一个字符串中至少重复出现两次的字串的个数(重复出现时不能重叠). code: 后缀数组处理,对于得到height 进行查找...  参考http://blog.csdn.net/mishifangxiangdefeng/article/details/7109211博主的详细的代码思路 #include<iostream> #include<string> using namespace std; #define N 1200 string s; *N], rank…
后缀数组三·重复旋律3 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分. 旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过.小Hi想知道两部作品的共同旋律最长是多少? 解题方法提示 输入 共两行.一…
Language: Default Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 21228   Accepted: 8708 Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes…
学后缀数组后的一道裸题.先来讲讲收获,作为字符串初学者,后缀数组也是刚刚在学,所幸的是有一篇好的论文<后缀数组--处理字符串的有力工具>by 罗穗骞,里面非常详尽地介绍了有关后缀数组的概念,也就是sa[i]和rk[i]表示的是什么.理解了它们互为逆运算后就不难理解sa[rk[i]]=i rk[sa[i]]=i,所以知道其中一个就可以知道另外一个,然后学习了一下后缀数组中的倍增算法构建,虽然效率比不上线性的算法,但是胜在好理解,好写.当然大神的代码我是不怎么懂,我就翻阅了另一本书<挑战程序…
题意:容易理解... 分析:这是我做的后缀数组第一题,做这个题只需要知道后缀数组中height数组代表的是什么就差不多会做了,height[i]表示排名第i的后缀与排名第i-1的后缀的最长公共前缀,然后我们可以枚举长度为k(1<=k<=len/2)的满足要求的子串个数,然后这个题的代码以后就作为求后缀数组的模板了!! 代码实现: #include<cstdio> #include<cstring> #include<cstdlib> #include<…
4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 169  Solved: 87[Submit][Status][Discuss] Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职加薪,出任CE O,嫁给高富帅,走上人生巅峰.…
题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大值.如果枚举 A和 B 的所有的后缀,那么这样做显然效率低下. 由于要计算 A 的后缀和 B 的后缀的最长公共前缀,所以先将第二个字符串写在第一个字符串后面,中间用一个没有出现过的字符隔开,再求这个新的字符串的后缀数组. 观察一下,看看能不能从这个新的字符串的后缀数组中找到一些规律.以 A=“aaa…
题意: 求两个串的最长连续子串. 我的想法: 枚举第二个串...在第一个串的后缀数组中二分查找. 复杂度NlogN.最坏情况N^2 题解: (3)height 数组:定义height[i]=suffix(SA[i-1])和suffix(SA[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀. (4) h[i]=height[rank[i]],也就是suffix(i)和在它前一名的后缀的最长公共前缀. (5)LCP(i,j):对正整数i,j 定义LCP(i,j)=lcp(Suffix(…
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然后维护出 L[i]数组表示:在后缀数组中,排名最小(记其排名为 L[i])的后缀与排名i的后缀的LCP>=hei[i]同理,R[i]数组表示:在后缀数组中,排名最大(记其排名为 R[i])的后缀与排名i的后缀的LCP>=hei[i]以上两个数组可以由单调栈 O(N)维护出来. 然后呢,令 ANS[…
这题说的是给了一串字符 我们要将这个字符 中找出至少出现m次的最长字符串 一个字符课多次使用 利用后缀数组计算最长的lcp 这里有一个点 记得将后缀数组中加入一个空串 如果遇到全部相同的字符时 没办法 判断 倒数第二个和 第三个的大小 因此他们就会被遗漏 #include <iostream> #include <algorithm> #include <cstdio> #include <vector> #include <string.h>…
仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通过二分+\(hash\)或者等等来优化字典序比较,复杂度\(O(n^2 \log n)\),可能要松一下 期望得分30分 ps:好吧有55分... 算法三 我们考虑字符集非常小的情况 我们猜想出题人很难卡掉玄学做法,因此我们就想一个玄学做法 我们考虑用\(SAM\)来处理这个问题 建出\(SAM\)…
题目大意:给定一个n个单词的文章,求每一个单词在文章中的出现次数 文章长度<=10^6(不是单词长度<=10^6,不然读入直接超时) 首先将全部单词用空格连接成一个字符串.记录每一个单词的起始位置和长度 然后求后缀数组,对于每一个单词后缀数组中一定有连续一段后缀以这个单词开头,我们通过一開始记录的起始位置找到这个单词的后缀,然后左右端点二分答案,满足左右端点之间的后缀与原单词的LCP都当与等于原单词长度就可以 时间复杂度O(nlogn) #include<cstdio> #incl…
题目大意 给定两个字符串A,B,求出A和B中最长公共子串的长度. 题目分析 字符串的子串可以认为是是字符串的某个后缀的前缀,而求最长公共子串相当于A和B的某两个后缀的最长相同前缀.可以考虑使用后缀数组,将A和B连接起来,中间添加一个在A和B中都未出现过的字符隔开,然后求这个新串的后缀数组以及height数组.**height数组是后缀Suffix(SA[i])和Suffix(SA[i-1])的公共前缀的最长长度.     容易知道,满足题目要求的两个子串S1,S2在后缀数组中肯定排名相邻(用反证…
后缀树: 字符串匹配算法一般都分为两个步骤,一预处理,二匹配. KMP和AC自动机都是对模式串进行预处理,后缀树和后缀数组则是对文本串进行预处理. 后缀树的性质: 存储所有 n(n-1)/2 个后缀需要 O(n) 的空间,n 为的文本(Text)的长度: 构建后缀树需要 O(dn) 的时间,d 为字符集的长度(alphabet): 对模式(Pattern)的查询需要 O(dm) 时间,m 为 Pattern 的长度: 介绍后缀树之前,我们首先要知道压缩字典树的概念. 我们在对关键字建立字典树的时…
模板奉上 int rank[maxn],height[maxn]; void calheight(int *r,int *sa,int n) { ; ;i<=n;i++) rank[sa[i]]=i; ;i<n;height[rank[i++]]=k) ,j=sa[rank[i]-];r[i+k]==r[j+k];k++) //求h[i] = height[rank[i]]; ; return; } 概念: (1)height 数组:定义height[i]=suffix(SA[i-1])和su…
题意:求最长不可重叠的相同差值子串的长度 这道题算是拖了好几个月,现在花了点时间应该搞懂了不少,尝试分析一下 我们首先来解决一个退化的版本,求最长不可重叠的相同子串(差值为0) 比如\(aabaabaa\), 那么所求的子串有\(aab,aba,baa\)三个 如何求?不妨枚举.枚举是否有长度为\(k\)的最长不可重叠相同子串 可是后缀数组中并不能直接表示出子串,只能间接地用后缀来表示 长度为\(k\)的相同子串\(=>\)最大公共前缀长度为\(k\)的子串\(=>\)最大公共前缀长度大于等于…
前言 看这篇博客前,先去了解一下后缀数组的基本操作吧:后缀数组入门(一)--后缀排序. 这篇博客的内容,主要建立于后缀排序的基础之上,进一步研究一个\(Height\)数组以及如何求\(LCP\). 什么是\(LCP\) \(LCP\),即\(Longest\ Common\ Prefix\),是最长公共前缀的意思. 而在后缀数组中,\(LCP(i,j)\)表示后缀\(_{SA_i}\)与后缀\(_{SA_j}\)的最长公共前缀的长度,注意是\(SA_i\)和\(SA_j\),而不是\(i\)和…
给一个字符串求有多少个不相同子串. 每一个子串一定都是某一个后缀的前缀.由此可以推断出总共有(1+n)*n/2个子串,那么下面的任务就是找这些子串中重复的子串. 在后缀数组中后缀都是排完序的,从sa[1]到sa[n],这么思考以某个串为前缀的子串有几个,那么容易想到重复子串的个数其实就是∑height[i]. 所以结果就是(1+n)*n/2-∑height[i]. #include<cstdio> #include<cstring> #include<algorithm>…
Time limit per test: 1.0 seconds Memory limit: 256 megabytes 子串的定义是在一个字符串中连续出现的一段字符.这里,我们使用 s[l…r] 来表示 s 字符串从 l 到 r(闭区间)的子串.在本题中,字符串下标从 0 开始.显然,对于长度为 n 的字符串共有 n(n+1)2 个子串. 对于一个给定的字符串 s,唐纳德给出 q 次询问,第 i 次询问包括三个参数 li,ri,zi,问在 s[li…ri] 的所有子串中共有多少个恰好为 zi.…
字符加密Cipher bzoj-1031 JSOI-2007 题目大意:题目链接. 注释:略. 想法: 后缀数组裸题啊. 后缀数组其实背下来板子之后有几个数组记住就可以了. $sa_i$表示排名为$i$的后缀所对应的下标. $rk_i$表示下标为$i$的后缀的排名. $ht_i$表示排名为$i$的后缀和排名为$i-1$的后缀之间的最长公共前缀. 因为是环,所以我们将字符串倍长. 然后对倍长的串建立后缀数组. 显然按照题目要求拍好序后的$n$个长度为$n$的串的相对位置,和刚才我们建好的后缀数组中…
Tyvj传送门 luogu传送门 经典题 统计一个字符串中不同子串的个数 一个字符串中的所有子串就是所有后缀的前缀 先求出后缀数组,求出后缀数组中相邻两后缀的 lcp 那么按照后缀数组中的顺序遍历求解 每一个后缀 suffix(sa[i]) 对于答案的贡献为 len - sa[i] - height[i] len - sa[i] 为当前后缀的长度,也就是当前后缀所有前缀的个数(字符串从 0 开始) height[i] 就是相邻两后缀 lcp,因为有可能会有相同前缀,而相同前缀在前面已经计算过了…
用Manacher算法枚举回文子串,每次在后缀数组排序后的后缀数组中二分,因为用某一后缀和其他子串分别求匹配的长度,匹配长度在排序后该后缀的两侧具有单调性(匹配长度为min{H[x]|i<=x<=j},所以对于查询min(H[x])用ST表O(n)预处理,O(1)查询即可.Manacher时间复杂度O(n),后缀数组复杂度O(nlogn),总复杂度O(nlogn).注意二分时的边界条件! #include <iostream> #include <cstdio> #in…
题意 : 给出一个长度为 N 的序列,再给出一个 K 要求求出出现了至少 K 次的最长可重叠子串的长度 分析 : 后缀数组套路题,思路是二分长度再对于每一个长度进行判断,判断过程就是对于 Height 数组进行限定长度的分组策略,如果有哪一组的个数 ≥  k 则说明可行! 分组要考虑到一个事实,对于每一个后缀,与其相匹配能够产生最长的LCP长度的串肯定是在后缀数组中排名与其相邻. 一开始对分组的理解有误,所以想了一个错误做法 ==> 遍历一下 Height 将值 ≥ (当前二分长度) 的做一次贡…