![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
后缀数组
Love_xyh
这个作者很懒,什么都没留下…
展开
-
CF1120C Compress String
朴素算法n^2求最长公共后缀#include <bits/stdc++.h>using namespace std;const int N=5e3+5;int n,a,b;int f[N],g[N][N];char str[N];int main(){ scanf("%d%d%d",&n,&a,&b); scanf("%s",str+1); for (register int i=1; i<n; ++i) for (register int原创 2020-09-21 20:05:02 · 158 阅读 · 0 评论 -
[JSOI2007]字符加密
将字符串进行复制,后缀排序后,对sa[i]进行查找。若sa[i]<=len,则输出s[sa[i]+len-1]即可。应该算是SA最裸的题了,不需要求height。#include <bits/stdc++.h>using namespace std;const int N=2e6+5;int n,m,len;int sum[N],rk[N],rk2[N],tp[N],sa[N],height[N];char s[N];inline void qsort(){ for原创 2020-09-19 09:00:17 · 880 阅读 · 0 评论 -
[USACO06DEC]Milk Patterns G
我们想要得到一个:至少出现k次的子串的最长长度。后缀排序后可得:含有这个"出现k次的子串"的后缀,必定是连续的,且前若共有k个连续的后缀拥有这个“出现k次的子串”,那么他们连续的区间一段lcp的最小值,一定就是这个“出现k次的子串”的最大值了。所以,求出height以后,找出:区间长度为k-1的区间的最大的最小值。单调队列或二分求解。由于本菜菜单调队列还是会的(单调栈实在恶心),所以就偷懒写这个码量较小的了…#include <bits/stdc++.h>using namespac原创 2020-09-18 20:29:35 · 190 阅读 · 0 评论 -
[AHOI2013]差异
两个后缀i,j的lcp,其实就是:min(height[k]) ,i+1<=k<=j。所以这一部分的总和就是:height数组[2,n]内,每一区间的最小值之和。考虑用二分+ST表来求和。暴露了菜鸡不会写单调栈的事实…#include <bits/stdc++.h>#define int long longusing namespace std;const int N=5e5+5;int n,m,ans;int sum[N],rk[N],rk2[N],tp[N],s原创 2020-09-18 20:20:10 · 121 阅读 · 0 评论 -
洛谷 P2408 不同子串个数
我们可以想到这样的一种计数方法:后缀[n,n]:有多少个不同串后缀[n-1,n]:有多少个不同串后缀[n-2,n]:有多少个不同串…最后答案减去重复的串。(发现无法统计答案)那么改变一下顺序,将这些后缀按照字典序排序后,我们也可以得到另一种顺序来进行计数:字典序第一小的后缀:有多少个不同串字典序第二小的后缀:有多少个不同串字典序第三小的后缀:有多少个不同串…我们可以发现,排序以后的,i从2开始,第i个串和第i-1个串,他们相同的串的个数,就是height[i]。而初始,串的个数一共为原创 2020-09-18 20:13:56 · 226 阅读 · 0 评论 -
洛谷 P3809 【模板】后缀排序
基数排序因为每次只有我们所谓的“第一关键字”和“第二关键字”,所以是一次排序复杂度为O(2n),对len进行倍增,所以只要进行log n次排序。所以总复杂度:O(n log n)。#include <bits/stdc++.h>using namespace std;const int N=1e6+5;int n,m;int rk[N],rk2[N],sum[N],tp[N],sa[N];char s[N];inline void qsort(){ for (register原创 2020-09-16 20:44:40 · 99 阅读 · 0 评论