原题传送门

实际按照题意模拟就行

我们先求出字符串的sa

因为要在字符串中出现k次,所以我们枚举\(l,r(r-l+1=k)\)看一共有多少种合法的方案

合法方案的长度下界\(lb\)为\(Max(height[l],lcp(l,r+1))+1\),这样保证子串在[1,l-1]和[r+1,len]中不会作为前缀

合法方案的长度上界\(rb\)为\(lcp(l,r)\),毕竟要求的是出现了k次的字串

如果\(lb<=rb\)我们就进行差分,否则就是没有可行方案

最后差分求前缀和时顺带比最大值即可

数据千万条,清空第一条。

多测不清空,爆零两行泪。

#include <bits/stdc++.h>
#define N 100005
using namespace std;
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline int Min(register int a,register int b)
{
return a<b?a:b;
}
inline int Max(register int a,register int b)
{
return a>b?a:b;
}
char s[N];
int n,size,tp[N],rak[N],sa[N],tex[N],height[N];
int lg2[N],st[N][25];
inline void Qsort()
{
for(register int i=0;i<=size;++i)
tex[i]=0;
for(register int i=1;i<=n;++i)
++tex[rak[i]];
for(register int i=1;i<=size;++i)
tex[i]+=tex[i-1];
for(register int i=n;i>=1;--i)
sa[tex[rak[tp[i]]]--]=tp[i];
}
inline void sa_build()
{
for(register int i=1;i<=(n<<1)&&i<N;++i)
tp[i]=rak[i]=0;
size=30;
for(register int i=1;i<=n;++i)
rak[i]=s[i]-'a'+1,tp[i]=i;
Qsort();
for(register int w=1,p=0;p<n;size=p,w<<=1)
{
p=0;
for(register int i=1;i<=w;++i)
tp[++p]=n-w+i;
for(register int i=1;i<=n;++i)
if(sa[i]>w)
tp[++p]=sa[i]-w;
Qsort();
swap(tp,rak);
rak[sa[1]]=p=1;
for(register int i=2;i<=n;++i)
rak[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p;
}
}
inline void getheight()
{
int k=0;
for(register int i=1;i<=n;++i)
{
if(k)
--k;
int j=sa[rak[i]-1];
while(s[i+k]==s[j+k])
++k;
height[rak[i]]=k;
}
}
inline void st_build()
{
memset(st,0,sizeof(st));
for(register int i=1;i<=n;++i)
st[i][0]=height[i];
for(register int j=1;(1<<j)<=n;++j)
for(register int i=1;i+(1<<j)-1<=n;++i)
st[i][j]=Min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
inline int getlcp(register int l,register int r)
{
++l;
int k=lg2[r-l+1];
return Min(st[l][k],st[r-(1<<k)+1][k]);
}
int T,m,cnt[N];
int main()
{
lg2[0]=-1;
for(register int i=1;i<N;++i)
lg2[i]=lg2[i>>1]+1;
lg2[0]=0;
scanf("%d",&T);
while(T--)
{
scanf("%s%d",s+1,&m);
n=strlen(s+1);
sa_build();
getheight();
st_build();
memset(cnt,0,sizeof(cnt));
for(register int i=1,x;i<=n;++i)
if(m==1)
{
if((x=Max(height[i],height[i-1]))<n-sa[i]+1);
++cnt[x+1],--cnt[n-sa[i]+2];
}
else
{
int l=Max(height[i],getlcp(i,i+m))+1;
int r=getlcp(i,i+m-1);
if(l<=r)
++cnt[l],--cnt[r+1];
}
for(register int i=1;i<=n;++i)
cnt[i]+=cnt[i-1];
int ans=0;
for(register int i=n;i>=1;--i)
if(cnt[i]>cnt[ans])
ans=i;
if(ans)
write(ans),puts("");
else
puts("-1");
}
return 0;
}

【题解】Luogu P5341 [TJOI2019]甲苯先生和大中锋的字符串的更多相关文章

  1. luogu P5341 [TJOI2019]甲苯先生和大中锋的字符串

    传送门 考虑子串以及出现个数,可以发现SAM可以快速知道每种子串的出现次数,即所在状态的\(endpos\)集合大小,然后一个状态对应的子串长度是一段连续区间,所以可以对每个状态差分一下,就能统计答案 ...

  2. 洛谷P5341 [TJOI2019]甲苯先生和大中锋的字符串

    原题链接P5341 [TJOI2019]甲苯先生和大中锋的字符串 题目描述 大中锋有一个长度为 n 的字符串,他只知道其中的一个子串是祖上传下来的宝藏的密码.但是由于字符串很长,大中锋很难将这些子串一 ...

  3. p5341 [TJOI2019]甲苯先生和大中锋的字符串

    分析 TJOI白给题 建出sam,对于每个点如果它的子树siz和等于k 那么对于这个满足的点它有贡献的长度一定是一个连续区间 直接差分即可 代码 #include<bits/stdc++.h&g ...

  4. [TJOI2019]甲苯先生和大中锋的字符串——后缀自动机+差分

    题目链接: [TJOI2019]甲苯先生和大中锋的字符串 对原串建后缀自动机并维护$parent$树上每个点的子树大小,显然子树大小为$k$的节点所代表的子串出现过$k$次,那么我们需要将$[len[ ...

  5. 【洛谷 P5341】 [TJOI2019]甲苯先生和大中锋的字符串(后缀自动机)

    题目链接 建出\(sam\),求出parent tree上每个点的\(endpos\)集合大小. 如果等于\(k\),说明到达这个点的都可以.给\((len[fa(i)],len[i]]\)的\(cn ...

  6. Tjoi2019 甲苯先生和大中锋的字符串 后缀自动机_差分

    tjoi胆子好大,直接出了两道送分题...... 都 9102 年了,还有省选出模板题QAQ...... Code: #include <bits/stdc++.h> #define se ...

  7. [TJOI2019]甲苯先生和大中锋的字符串

    有个叫asuldb的神仙来嘲讽我 说这题SAM水题,而且SA过不了 然后我就用SA过了 显然是一个Height数组上长为k的滑块,判一下两边,差分一下就可以了 #include"cstdio ...

  8. 【题解】Luogu P5337 [TJOI2019]甲苯先生的字符串

    原题传送门 我们设计一个\(26*26\)的矩阵\(A\)表示\(a~z\)和\(a~z\)是否能够相邻,这个矩阵珂以由\(s1\)得出.答案显然是矩阵\(A^{len_{s2}-1}\)的所有元素之 ...

  9. 【题解】Luogu P5338 [TJOI2019]甲苯先生的滚榜

    原题传送门 这题明显可以平衡树直接大力整,所以我要说一下线段树+树状数组的做法 实际线段树+树状数组的做法也很暴力 我们先用树状数组维护每个ac数量有多少个队伍.这样就能快速求出有多少队伍ac数比现在 ...

随机推荐

  1. JS回调函数怎么写的?

    相信每个做前端的同学都用过太多太多的回调函数, 接下来就看看回调函数是怎么来的. 这玩意儿也没那么神秘,直接看代码: 声明函数的时候,把回调函数用作参数,并且在函数内调用它 function getD ...

  2. DevExpress.XtraEditors.Repository.RepositoryItem.CreateDesigner()

    未将对象引用设置到对象的实例.              此错误的实例(1)   1.   隐藏调用堆栈  在 DevExpress.XtraEditors.Repository.Repository ...

  3. linux高性能服务器编程 (三) --TCP协议详解

    第三章 IP协议详解 TCP协议是TCP/IP协议族中的另外一个重要的协议,与IP协议相比,TCP协议更高进应用层.一些重要的socket选项都和TCP协议相关.这一章主要从如下方面学习: 1)TCP ...

  4. Django实现自动发布(3发布-安装)

    相对于服务的升级.回退,新部署一个服务要复杂一些,要满足以下要求: 已经运行了服务实例的主机不能重复部署 进程启动需要的配置文件要先同步到主机上 之前的升级.回退都是指进程的操作,不涉及配置文件的变更 ...

  5. 使用analyze命令统计信息

    ① 搜集和删除索引.表和簇的统计信息② 验证表.索引和簇的结构③ 鉴定表和簇和行迁移和行链接针对analyze的搜集和删除统计信息功能而言Oracle推荐使用DBMS_STATS包来代替analyze ...

  6. PostgreSQL DISTINCT 和 DISTINCT ON

    select语句中,使用distinct关键字,在处理select list后,结果表可以选择消除重复的行.在SELECT之后直接写入DISTINCT关键字以指定此关键字: SELECT DISTIN ...

  7. spring boot允许跨域(CORS)的配置

    添加@Configuration配置类即可. @Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { ...

  8. ES开启慢查询日志

    默认情况,慢日志是不开启的.要开启它,需要定义具体动作(query,fetch 还是 index),你期望的事件记录等级( WARN.INFO.DEBUG.TRACE 等),以及时间阈值. es有几种 ...

  9. MQTT研究之EMQ:【EMQX使用中的一些问题记录(2)】

    我的测试环境: Linux: CentOS7 EMQX:V3.2.3 题外话: 这里主要介绍Websocket的支持问题. 对ws的支持比较正常,但是对wss的支持,调了较长的时间,没有成功. Jav ...

  10. github加速

    访问 https://www.ipaddress.com/ 找到以下网址对应的ip,在本地hosts里面映射,或者到路由器内映射好即可. github.com assets-cdn.github.co ...