[TJOI2019]甲苯先生和大中锋的字符串
有个叫asuldb的神仙来嘲讽我
说这题SAM水题,而且SA过不了
然后我就用SA过了
显然是一个Height数组上长为k的滑块,判一下两边,差分一下就可以了
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1e5+5;
int n,T,mx,hd,tl;
char ch[MAXN];
int id[MAXN],rnk[MAXN],SA[MAXN],bnk[MAXN],Ht[MAXN];
int cnt[MAXN],q[MAXN];
int read()
{
int x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x;
}
void shel()
{
for(int i=1;i<=n;++i) ++bnk[rnk[i]];
for(int i=1;i<=mx;++i) bnk[i]+=bnk[i-1];
for(int i=1;i<=n;++i) SA[++bnk[rnk[id[i]]-1]]=id[i];
for(int i=0;i<=mx;++i) bnk[i]=0;
}
void GetSA()
{
mx=0;
for(int i=1;i<=n;++i) id[i]=i,rnk[i]=ch[i],mx=mx<rnk[i]?rnk[i]:mx;
shel();
for(int k=1;k<n;k<<=1){
for(int i=1;i<=k;++i) id[i]=n-k+i;
int ct=k;
for(int i=1;i<=n;++i) if(SA[i]>k) id[++ct]=SA[i]-k;
shel();swap(rnk,id);rnk[SA[1]]=1;
for(int i=2;i<=n;++i){
if(id[SA[i]]==id[SA[i-1]]&&id[SA[i]+k]==id[SA[i-1]+k]) rnk[SA[i]]=rnk[SA[i-1]];
else rnk[SA[i]]=rnk[SA[i-1]]+1;
}if(rnk[SA[n]]==n) break;
mx=rnk[SA[n]];
}return;
}
void GetHt()
{
int k=0;
for(int i=1;i<=n;++i){
if(rnk[i]==1) continue;
int tmp=SA[rnk[i]-1];
k=k?k-1:0;
while(tmp+k<=n&&i+k<=n&&ch[i+k]==ch[tmp+k]) ++k;
Ht[rnk[i]]=k;
}return;
}
int GetLCP(int x,int y)
{
if(x>y) return n-SA[y]+1;
return Ht[q[hd]];
}
int main()
{
T=read();
while(T--){
memset(id,0,sizeof(id));
memset(cnt,0,sizeof(cnt));
scanf("%s",ch+1);n=strlen(ch+1);
int w;scanf("%d",&w);Ht[n+1]=0;
GetSA(),GetHt();hd=1;tl=0;
for(int i=2;i<=w;++i){
while(hd<=tl&&Ht[q[tl]]>=Ht[i]) --tl;
q[++tl]=i;
}for(int i=w;i<=n;++i){
if(i-q[hd]+1>=w) ++hd;
while(hd<=tl&&Ht[q[tl]]>=Ht[i]) --tl;
q[++tl]=i;
int tmp=GetLCP(i+1,i+w-1);
int g=max(Ht[i-w+1],Ht[i+1]);
if(g<=tmp) ++cnt[g+1],--cnt[tmp+1];
}int tmp=-1,mm=1;
for(int i=1;i<=n;++i){
cnt[i]+=cnt[i-1];
if(cnt[i]>=mm) mm=cnt[i],tmp=i;
}printf("%d\n",tmp);
}return 0;
}
[TJOI2019]甲苯先生和大中锋的字符串的更多相关文章
- [TJOI2019]甲苯先生和大中锋的字符串——后缀自动机+差分
题目链接: [TJOI2019]甲苯先生和大中锋的字符串 对原串建后缀自动机并维护$parent$树上每个点的子树大小,显然子树大小为$k$的节点所代表的子串出现过$k$次,那么我们需要将$[len[ ...
- 洛谷P5341 [TJOI2019]甲苯先生和大中锋的字符串
原题链接P5341 [TJOI2019]甲苯先生和大中锋的字符串 题目描述 大中锋有一个长度为 n 的字符串,他只知道其中的一个子串是祖上传下来的宝藏的密码.但是由于字符串很长,大中锋很难将这些子串一 ...
- Tjoi2019 甲苯先生和大中锋的字符串 后缀自动机_差分
tjoi胆子好大,直接出了两道送分题...... 都 9102 年了,还有省选出模板题QAQ...... Code: #include <bits/stdc++.h> #define se ...
- 【题解】Luogu P5341 [TJOI2019]甲苯先生和大中锋的字符串
原题传送门 实际按照题意模拟就行 我们先求出字符串的sa 因为要在字符串中出现k次,所以我们枚举\(l,r(r-l+1=k)\)看一共有多少种合法的方案 合法方案的长度下界\(lb\)为\(Max(h ...
- 【洛谷 P5341】 [TJOI2019]甲苯先生和大中锋的字符串(后缀自动机)
题目链接 建出\(sam\),求出parent tree上每个点的\(endpos\)集合大小. 如果等于\(k\),说明到达这个点的都可以.给\((len[fa(i)],len[i]]\)的\(cn ...
- luogu P5341 [TJOI2019]甲苯先生和大中锋的字符串
传送门 考虑子串以及出现个数,可以发现SAM可以快速知道每种子串的出现次数,即所在状态的\(endpos\)集合大小,然后一个状态对应的子串长度是一段连续区间,所以可以对每个状态差分一下,就能统计答案 ...
- p5341 [TJOI2019]甲苯先生和大中锋的字符串
分析 TJOI白给题 建出sam,对于每个点如果它的子树siz和等于k 那么对于这个满足的点它有贡献的长度一定是一个连续区间 直接差分即可 代码 #include<bits/stdc++.h&g ...
- [TJOI2019]大中锋的游乐场——最短路+DP
题目链接: [TJOI2019]大中锋的游乐场 题目本质要求的还是最短路,但因为有第二维权值(汽水看成$+1$,汉堡看成$-1$)的限制,我们在最短路的基础上加上一维$f[i][j]$表示到达$i$节 ...
- [TJOI2019]甲苯先生的字符串——矩阵乘法+递推
题目链接: [TJOI2019]甲苯先生的字符串 我们用一个$26*26$的$01$矩阵记录任意两个字符是否能相邻. 设$f[i][j]$表示处理完前$i$个字符,第$i$个字符为$j$的方案数. 可 ...
随机推荐
- go语言学习---使用os.Args获取简单参数(命令行解析)
实例1: //main package main import ( "fmt" "os" ) func main() { fmt.Println(os.Args ...
- java程序员必须熟悉的一些操作
1.mysql数据库服务启动命令 /etc/init.d/mysqld start --启动命令 mysql数据库安装方法参考 http://www.blogja ...
- TeX 家族(TeX, pdfTeX, XeTeX, LuaTeX, LaTeX, pdfLaTeX, XeLaTeX …)
TeX 家族 带有 TeX 的词,仅仅是本文就已经提到了 TeX, LaTeX, XeLaTeX.通常中国学生面对不了解意思的一群形近单词,都会有一种「本能的恐惧」(笑~).因此,「大神们」在为新手介 ...
- quartz 定时器执行
类存储job信息 public class JobInfo {//省略setter getter String jobName; String jobGroup; Class<? extends ...
- SSM框架之MyBatis入门介绍
一.什么是MyBatis? MyBatis源自Apache的iBatis开源项目, 从iBatis3.x开始正式更名为MyBatis.它是一个优秀的持久层框架. 二.为什么使用MyBatis? 为了和 ...
- mysql 的使用
1. 安装 https://dev.mysql.com/downloads/mysql/ 2. 配置 $ vim ~/.bash_profile $ export PATH=$PATH:/usr/lo ...
- orangepi获取cpu温度
cat /sys/devices/virtual/hwmon/hwmon1/temp1_input
- jenkens + github
一 获取github accessToken 依次点击 settings----> Developer settings --->Personal access tokens 到这里如 ...
- 用java代码实现构造目录树
怎么用java代码实现上面这样的目录树? 首先创建数据表 每条数据记录自己的id以及父节点的id 然后进入java代码部分: public String directory(String author ...
- O - Can you find it?(二分查找)
O - Can you find it? Time Limit:3000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64 ...