[BZOJ3230] 相似字串 后缀数组+RMQ】的更多相关文章

3230: 相似子串 Time Limit: 20 Sec  Memory Limit: 128 MB Description Input 输入第1行,包含3个整数N,Q.Q代表询问组数.第2行是字符串S.接下来Q行,每行两个整数i和j.(1≤i≤j). Output 输出共Q行,每行一个数表示每组询问的答案.如果不存在第i个子串或第j个子串,则输出-1. Sample Input 5 3 ababa 3 5 5 9 8 10 Sample Output 18 16 -1 HINT 样例解释 第…
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=1770 题解:一开始理解错题意,以为是abcxxxcba(xxx为v),开心地打了后缀数组后发现哎样例不对丫.. UVA的意思是abcxxxabc(xxx为v). 类似poj3693,我们暴…
A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed string t with length l>=1. For example, the string s = abaabaabaaba is a (4,3)-repeat with t = aba as its seed string. That is, the seed string t is 3 charac…
替换某个字符串中的一个或若干个字串为数组中某些值 php本身有自带的函数,可以不用循环非常高效的实现其效果: 实例代码:   $phrase  = "You should eat fruits , vegetables, and fiber every day.";  $healthy = array("fruits", "vegetables", "fiber");  $yummy   = array("pizza…
思路: 论文题 后缀数组&RMQ 有一些题解写得很繁 //By SiriusRen #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 100050 int n,cases,cntA[N],cntB[N],A[N],B[N],rk[N],sa[N],tsa[N],ht[N],f[N][18],…
CF原题(http://codeforces.com/blog/entry/4849, 204E), CF的解法是O(Nlog^2N)的..记某个字符串以第i位开头的字符串对答案的贡献f(i), 那么f(i-1)>=f(i)-1, 然后就是O(NlogN)了, 但是速度垫底了....被后缀自动机完爆了... ----------------------------------------------------------------------------------------------…
题目大意: 在原串中找到一个拥有连续相同子串最多的那个子串 比如dababababc中的abababab有4个连续的ab,是最多的 如果有同样多的输出字典序最小的那个 这里用后缀数组解决问题: 枚举连续子串的长度l , 那么从当前位置0出发每次递增l,拿 i 和 i+l 开头的后缀求一个前缀和val , 求解依靠RMQ 得到区间 rank(i),rank(i+l) 那么连续的子串个数应该是val/l+1 但是由于你不一定是从最正确的位置出发,那么我们就需要不断将这个i往前推l位,直到某一位字符不…
题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会包含s[0].s[l].s[l*2]...之中的相邻的两个.不难看出,该重复子串必然会包含s[0..l]或s[l..l*2]或s[l*2..l*3]....所以,我们可以枚举一个i,对于每个i*l的位置,利用后缀数组可以求出s[i*l..(i+1)*l]向后延伸的长度k.k/l+1即i*l..(i+…
题意:就是让你求一个字符串中的最长回文,如果有多个长度相等的最长回文,那就输出第一个最长回文. 思路:这是后缀数组的一种常见的应用,首先把原始字符串倒转过来,然后接在原始字符串的后面,中间用一个不可能出现的字符隔开.然后就用到后缀数组的性质了, 我们枚举每一个原始字符串中的字符以它为中心(分为奇数和偶数两种情况)进行查找,比如对于下标为i的字符,当回文串为奇数时,我们要求的就是i的后缀与2*n-i的 后缀的最长公共前缀了,然后根据height数组的性质就转化成求height[i+1]...hei…
3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一行n个整数,第i个整数表示第i个字符串的答案. Sample Input 3 1 abc a ab Sample Output 6 1 3 HINT 对于 100% 的数据,1<=n,k<=10^5,所有字符串总长不超过10^5,字符串只包含小写字母. [分析] 这道题用后缀数…
The Number of Palindromes Problem Description Now, you are given a string S. We want to know how many distinct substring of S which is palindrome. Input The first line of the input contains a single integer T(T<=20), which indicates number of test ca…
常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割 由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串中出现过 那我们就二分一下这个前缀的长度.现在的问题就是怎么判断这个前缀是否在K个串中出现过了. 显然,对于一个后缀s的长度为x的前缀,只要某个后缀t 和s的LCP>=x,就说明x也是t的后缀 我们知道,LCP(x,y)=min{height[rank[y]],height[rank[y]-1],.…
题目链接 后缀自动机做法见这(超好写啊). 后缀数组是可以做的: 本质不同的字符串的个数为 \(子串个数-\sum_{ht[i]}\),即 \(\frac{n(n+1)}{2}-\sum_{ht[i]}\). 如果是每次往后边插入字符,会改变SA[].但如果向前边插入字符,相当于只加入了一个后缀. 所以离线,把原串反过来. 每次插入一个字符,即新增一个前缀i,它的贡献是\(len-max(lcp(pre,i),lcp(i,nxt))\),其中\(pre,nxt\)为与后缀\(i\)(当前)排名相…
E. Liar     The first semester ended. You know, after the end of the first semester the holidays begin. On holidays Noora decided to return to Vičkopolis. As a modest souvenir for Leha, she brought a sausage of length m from Pavlopolis. Everyone know…
/* 源程序丢失QWQ. 就不粘代码了. 大体做法是把串反转然后连接. 做一遍后缀数组. 对height做一遍rmq. 然后对于每个位置的奇偶分别判断, 记下pos. 注意求的是[l+1,r]的height值. */…
[POI2000] 公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. Solution 预处理出后缀数组和高度数组,二分答案 \(k\) ,对于每一个连续的 \(RMQ\) 大于等于 \(k\) 的段,判断其中是否有来源于每一个串的后缀即可. #include <bits/stdc++.h> using namespace std; int n,m=256,sa[1000005],y[1000005],u[1000005],v[1000005],o[1…
题意: 给定一个串\(s\),\(s\)必有一个最大循环节的连续子串\(ss\),问最大循环次数是多少 思路: 我们可以知道,如果一个长度为\(L\)的子串连续出现了两次及以上,那么必然会存在\(s[0].s[L].s[2L] \cdots s[L * k]\)中至少有两个连续的位置是相同的,然后看字母\(s[L * i]和s[L * (i + 1)]\)往前往后最多能匹配多远,记住总长度\(len\),那么最大循环次数为\((len / L) + 1\). 参考: SPOJ 687. Repe…
题意:给定一个字符串,求重复次数最多的连续重复子串. 传说中的后缀数组神题,蒟蒻真的调了很久才对啊.感觉对后缀数组和RMQ的模版都不是很熟,导致还是会有很多各种各样的小错误= = 首先,枚举重复子串的循环节为L,因为枚举的是循环节长度,所以是没有单调性的,那么枚举就要用0(n)的时间了.连续一次的情况是可以的,所以这里只考虑重复两次或以上的情况. 记这个连续重复子串为L,我们可以发现,这个字符串一定会覆盖s[0],s[L],s[L*2].....这些点中相邻的两个(因为长度至少为2L嘛).假设它…
传送门 后缀数组入门题. 建立正反两个后缀数组算就行了. 代码: #include<bits/stdc++.h> #define ri register int using namespace std; typedef long long ll; const int N=2e5+5; int n,m,q,sa2[N],Log[N],cnt[N]; ll num[N]; char s[N]; struct SA{ int sa[N],rk[N],ht[N],st[N][21]; inline v…
[BZOJ2946][Poi2000]公共串 Description        给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单词 l        计算最长公共子串的长度 l        输出结果 Input 文件的第一行是整数 n,1<=n<=5,表示单词的数量.接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000. Output 仅一行,一个整数,最长公共子串的长度. Sample Input 3 abcb bca…
题意 题目链接 Sol 这题打死我也不会想到后缀数组的,应该会全程想AC自动机之类的吧 但知道这题能用后缀数组做之后应该就不是那么难了 首先把\(S\)和\(S0\)拼到一起跑,求出Height数组 暴力枚举每个后缀是否能成为答案. 具体来说,每次比较当前后缀和\(S_0\)的lcp,如果长度\(< N\)的话就从不合法的位置继续匹配 rmq维护一下区间lcp最小值 BZOJ上被完美卡常 // luogu-judger-enable-o2 #include<bits/stdc++.h>…
string string string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 608    Accepted Submission(s): 167 Problem Description Uncle Mao is a wonderful ACMER. One day he met an easy problem, but U…
好绝望的..想了五个多小时,最后还是没A...赛后看了下后缀数组瞬间就有了思路...不过因为太菜,想了将近两个小时才吧这个题干掉. 首先,应当认为,后缀数组的定义是,某字符串S的所有后缀按照字典序有小到大的顺序排列(使用下标表示后缀).因为具体过程没太看懂,但是参见刘汝佳蓝书<算法竞赛黑暗圣典>可以得到一个聪明的NLOGN的神器算法.不过这个不太重要. 之后还可以通过他在LCP问题中提到的RANK,height数组相关算法,处理出来height数组,之后其他的可以扔掉. <黑暗圣典>…
题意:求一个序列中本质不同的连续子序列的最大值之和. 由于要求“本质不同”,所以后缀数组就派上用场了,可以从小到大枚举每个后缀,对于每个sa[i],从sa[i]+ht[i]开始枚举(ht[0]=0),这样就能不重复不遗漏地枚举出每一个子串. 但是这样做,最坏情况仍旧是$O(n^2)$的,可能会被卡掉,需要进一步优化. 对于每个sa[i],设k=sa[i]+ht[i],则问题转化成了求max(s[sa[i]],s[sa[i]+1],...,s[k])+max(s[sa[i]],s[sa[i]+1]…
[BZOJ3277] 串 Description 现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Solution 首先将所有串连接起来,预处理出后缀数组和高度数组. 显然直接主席树可以很容易做到 \(O(n \log^2 n)\) .对于每一个后缀的位置,二分一个 LCP 长度,找到这个 LCP 长度对应的区间,检查这个区间是否合法来调节二分边界. 注意在这个做法里,瓶颈不在于主席树,因为主席树的功能完全可以用双指针预处理一…
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defin…
思路: 求一发后缀数组,求个LCP 就好了 注意数字有可能不只一位 (样例2) //By SiriusRen #include <bits/stdc++.h> using namespace std; ; char s[N]; ]; int n,t,base[N],l[N],r[N]; void SA(){ ;i<=;i++)cntA[i]=; ;i<=n;i++)cntA[s[i]]++; ;i<=;i++)cntA[i]+=cntA[i-]; for(int i=n;i;…
后缀数组+Manacher #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> using namespace std; long long Ans; ],B[],U[]; ],*Rank,H[],Tmp[]; ],…
[BZOJ3230]相似子串 Description Input 输入第1行,包含3个整数N,Q.Q代表询问组数.第2行是字符串S.接下来Q行,每行两个整数i和j.(1≤i≤j). Output 输出共Q行,每行一个数表示每组询问的答案.如果不存在第i个子串或第j个子串,则输出-1. Sample Input 5 3 ababa 3 5 5 9 8 10 Sample Output 18 16 -1 HINT 样例解释第1组询问:两个子串是“aba”,“ababa”.f = 32 + 32 =…
[BZOJ4698]Sdoi2008 Sandy的卡片 Description Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型.每一张卡片都由一些数字进行标记,第i张卡片的序列长度为Mi,要想兑换人物模型,首先必须要集够N张卡片,对于这N张卡片,如果他们都有一个相同的子串长度为k,则可以兑换一个等级为k的人物模型.相同的定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串.Sandy的卡…