【[HEOI2016/TJOI2016]字符串】】的更多相关文章

BZOJ 4556 [HEOI2016/TJOI2016]字符串 其实题解更多是用后缀数组+数据结构的做法,貌似也不好写. 反正才学了 sam 貌似比较简单的做法. 还是得先二分,然后倍增跳到 $ s[c...c+mid-1] $ 所在的节点,然后看看有没有 endpos 在 $ a+mid-1...b $ 内就好了. 复杂度是二分和倍增的 $ nlog^2n $. 其实这道题因为只用求 endpos 是否存在啥的 vector + lower_bound 貌似都可以过了..但其实启发式合并也不…
$ \color{#0066ff}{ 题目描述 }$ 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱子拿到礼物,升职加薪,出任CEO,嫁给高富帅,走上人生巅峰.每个问题均有a,b,c,d四个参数,问你子串s[a..b]的所有子串和s[c..d]的最长公共前缀的长度的最大值是多少?佳媛姐姐并不擅长做这样的问题,所以她向你求助,你该如何帮助她呢? \(\color{#00…
嘟嘟嘟 今天复习一下SAM. lcp固然不好做,干脆直接翻过来变成后缀.首先答案一定满足单调性,所以我们二分lcp的长度\(mid\),然后判断\(s[d \ldots d + mid - 1]\)是否在\(s[b \ldots a]\)(别忘了整个串是反过来的)中出现即可. 怎么判断是否出现呢?其实就是判断这个子串的endpos是否在\(s[b + mid - 1 \ldots a]\)中,因此我们要求出SAM上的每一个节点的endpos集合,这就要用到线段树合并了. 需要注意的是,并不是直接…
后缀数组解法: 先二分最长前缀长度 \(len\),然后从 \(rnk[c]\) 向左右二分 \(l\) 和 \(r\) 使 \([l,r]\) 的 \(height\geq len\),然后在主席树上查 \(sa[l..r]\) 是否有 \(a..b\) 中的任意一个数.时间复杂度 \(O(n\log^2 n)\) \(Code\ Below:\) #include <bits/stdc++.h> using namespace std; const int maxn=100000+10;…
码农题啊 上来先无脑一个\(SA\)的板子,求出\(SA\)和\(het\)数组 我们只需要从\(sa[i]\in[a,b]\)的所有\(i\)中找到一个\(i\)使得\(sa[i]\)和\(rk[c]\)之间的最小值最大就好了 但是还必须得满足\(sa[i]+lcp-1<=b\),毕竟整个串还得在\([a,b]\)内部 考虑一下二分答案 根据\(het\)数组的性质显然越靠近\(rk[c]\)的\(sa[i]\)形成的\(lcp\)越长,于是我们可以利用一个\(ST\)表加二分找到从\(rk[…
题意 考虑二分答案\(mid\),现在我们要判断\(s[c...c+mid-1]\)是否在\(s[a...b]\)出现过. 首先找到\(s[c...c+mid-1]\)所在的状态: 建出\(parent\ tree\),从\(s[1...c+mid-1]\)的节点(这个可以记录)用倍增向上跳到最后一个\(len\geqslant mid\)的节点即可,记这个节点为\(now\). 之后我们要判断\(now\)的\(endpos\)中是否含有\([a+mid-1,b]\)中的某个数,我们给每个节点…
二分答案后相当于判断一个区间的后缀与某个后缀的最长公共前缀是否能>=ans.建出后缀树,在上述问题中后者所在节点向上倍增的跳至len>=ans的最高点,然后相当于查询子树中是否有该区间的节点.主席树进行二维数点即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm&…
题目链接:戳我 非常不好意思,因为想要排版,所以今天先只把代码贴出来,明天补题解. 40pts暴力:直接暴力匹配 #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<cstdio> #define MAXN 100010 using namespace std; int n,m; char s[MAXN]; inline int sol…
题面传送门 一道码农题---- u1s1 感觉这类题目都挺套路的,就挑个有代表性的题写一篇题解罢. 首先注意到答案满足可二分性,故考虑二分答案 \(mid\),转化为判定性问题. 考虑怎样检验 \(mid\) 是否可行,它等价于是否存在 \(s[a...b]\) 中的一个子串 \(t\) 满足 \(s[c...c+mid-1]\) 为 \(t\) 的前缀.不过不难发现这个"前缀"是假的,因为 \(\forall a\le l\le r\le b\),\(s[l...r]\) 的任意一个…
hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; int n,k,T,xx; int ans[MAXN],c[MAXN],f[MAXN]; struct Node{ int x,y,z,id; }a[100010],b[100010]; inline int read(){ char ch; bool f=false; int res=0; while (…