[TJOI2019]甲苯先生和大中锋的字符串
IV.[TJOI2019]甲苯先生和大中锋的字符串
判断一个子串出现几次,我们仍然可以采取之前提到的遍历parent tree的方法。
考虑一个等价类。明显,这个等价类中所有串都出现且仅出现了(等价类出现的次数)。若这个次数恰好为 ,则从类中最长的串到最短的串,所有长度的串的数量都增加了 。于是用一个差分数组维护这一过程,最后找到其中出现最多的长度即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T,cnt,n,m;
struct Suffix_Automaton{int ch[26],len,fa;}t[200100];
int sz[200100];
int Add(int x,int c){
int xx=++cnt;t[xx].len=t[x].len+1;
sz[xx]=1;
for(;x&&!t[x].ch[c];x=t[x].fa)t[x].ch[c]=xx;
if(!x){t[xx].fa=1;return xx;}
int y=t[x].ch[c];
if(t[y].len==t[x].len+1){t[xx].fa=y;return xx;}
int yy=++cnt;t[yy]=t[y];
t[yy].len=t[x].len+1;
t[y].fa=t[xx].fa=yy;
for(;x&&t[x].ch[c]==y;x=t[x].fa)t[x].ch[c]=yy;
return xx;
}
vector<int>v[200100];
ll d[100100],mx;
void dfs(int x){for(auto y:v[x])dfs(y),sz[x]+=sz[y];}
char s[100100];
int main(){
scanf("%d",&T);
while(T--){
scanf("%s%d",s,&m),n=strlen(s),cnt=1,mx=0;
for(int i=0,las=1;i<n;i++)las=Add(las,s[i]-'a');
for(int i=2;i<=cnt;i++)v[t[i].fa].push_back(i);
dfs(1);
for(int i=2;i<=cnt;i++)if(sz[i]==m)d[t[t[i].fa].len]--,d[t[i].len]++;
for(int i=n;i;i--)d[i]+=d[i+1],mx=max(mx,d[i]);
if(!mx)puts("-1");
else for(int i=n;i;i--)if(d[i]==mx){printf("%d\n",i);break;}
for(int i=1;i<=cnt;i++){memset(t[i].ch,0,sizeof(t[i].ch)),t[i].len=t[i].fa=sz[i]=0,v[i].clear();}
for(int i=1;i<=n;i++)d[i]=0;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?