【后缀自动机】洛谷P3804模板题
题目描述
给定一个只包含小写字母的字符串S,
请你求出 S 的所有出现次数不为 1 的子串的出现次数乘上该子串长度的最大值。
输入输出格式
输入格式:
一行一个仅包含小写字母的字符串S
输出格式:
一个整数,为 所求答案
输入输出样例
abab
4
说明
对于10%的数据,|S|<=1000
对于100%的数据,|S|<=10^6
题解
只会后缀自动机的部分。。。
其他的是贴的欸嘿嘿
代码
//by 减维
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<bitset>
#include<set>
#include<cmath>
#include<vector>
#include<map>
#include<ctime>
#include<algorithm>
#define ll long long
#define db double
#define inf 1<<30
#define maxn 3000005
#define eps 1e-8
using namespace std; struct SAM{
int to[],par,len;
}e[maxn]; char a[maxn],st[maxn];
int last=,rt=,sz=,tot,siz[maxn],du[maxn],ax[maxn];
ll ans=; void add(int x)
{
int p=last,np=++sz;
e[np].len=e[p].len+;
for(;p&&!e[p].to[x];p=e[p].par) e[p].to[x]=np;
if(!p) e[np].par=rt;
else{
int q=e[p].to[x];
if(e[q].len==e[p].len+) e[np].par=q;
else{
int nq=++sz;
e[nq]=e[q];e[nq].len=e[p].len+;
e[np].par=e[q].par=nq;
for(;p&&e[p].to[x]==q;p=e[p].par) e[p].to[x]=nq;
}
}
last=np;
siz[np]=;
} void calc()
{
for(int i=;i<=sz;++i)du[e[i].len]++;
for(int i=;i<=sz;++i)du[i]+=du[i-];
for(int i=;i<=sz;++i)ax[du[e[i].len]--]=i;
for(int i=sz;i;--i)
{
int p=ax[i];
siz[e[p].par]+=siz[p];
if(siz[p]>)ans=max(ans,(ll)siz[p]*e[p].len);
}
} int main()
{
scanf("%s",a);
for(int i=;a[i];i++)add(a[i]-'a');
calc();
printf("%lld",ans);
return ;
}
学会后缀自动机了!(大概。。。)
反正自己想到了一个建出来后缀树的做法2333
代码
//by 减维
#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define il inline
#define db double
#define rg register
#define mpr make_pair
#define maxn 3000005
#define eps 1e-8
#define inf (1<<30)
#define pi 3.1415926535897932384626L
using namespace std; inline int read()
{
int ret=;bool fla=;char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-'){fla=;ch=getchar();}
while(ch>=''&&ch<=''){ret=ret*+ch-'';ch=getchar();}
return fla?-ret:ret;
} struct edge{
int to,ne;
}e[maxn<<]; int n,ecnt,siz[maxn],dis[maxn],head[maxn];
ll ans;
char s[maxn]; void add(int x,int y)
{
e[++ecnt]=(edge){y,head[x]};head[x]=ecnt;
//e[++ecnt]=(edge){x,head[y]};head[y]=ecnt;
} namespace SAM{
int to[maxn][],par[maxn],len[maxn];
int sz=,las=;
void ins(int x)
{
int p=las,np=++sz,q,nq;
las=np;len[np]=len[p]+;
for(;p&&!to[p][x];p=par[p]) to[p][x]=np;
if(!p) par[np]=;
else{
q=to[p][x];
if(len[q]==len[p]+) par[np]=q;
else{
nq=++sz;par[nq]=par[q];len[nq]=len[p]+;
memcpy(to[nq],to[q],sizeof to[q]);
par[q]=par[np]=nq;
for(;p&&to[p][x]==q;p=par[p]) to[p][x]=nq;
}
}
siz[np]=;
}
void build()
{
for(int i=;i<=sz;++i) add(par[i],i);//,printf("%d %d\n",i,par[i]);
}
} void dfs(int x)
{
//siz[x]=1;
for(int i=head[x];i;i=e[i].ne)
{
int dd=e[i].to;
dis[dd]=dis[x]+SAM::len[dd]-SAM::len[x];
dfs(dd);
siz[x]+=siz[dd];
}
if(siz[x]!=) ans=max(ans,1ll*siz[x]*dis[x]);
} int main()
{
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;++i) SAM::ins(s[i]-'a');
SAM::build();
dfs();
printf("%lld",ans);
return ;
}
【后缀自动机】洛谷P3804模板题的更多相关文章
- 【AC自动机】洛谷三道模板题
[题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...
- 【后缀数组】洛谷P3809模板题
题目背景 这是一道模板题. 题目描述 读入一个长度为 n n n 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...
- 【最大流ISAP】洛谷P3376模板题
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- 洛谷 P3804 [模板] 后缀自动机
题目:https://www.luogu.org/problemnew/show/P3804 模仿了一篇题解,感觉很好写啊. 代码如下: #include<cstdio> #include ...
- LCA算法倍增算法(洛谷3379模板题)
倍增(爬树)算法,刚刚学习的算法.对每一个点的父节点,就记录他的2k的父亲. 题目为http://www.luogu.org/problem/show?pid=3379 第一步先记录每一个节点的深度用 ...
- 洛谷 P4148 简单题 KD-Tree 模板题
Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 【noip】跟着洛谷刷noip题2
noip好难呀. 上一个感觉有点长了,重开一个. 36.Vigenère 密码 粘个Openjudge上的代码 #include<cstdio> #include<iostream& ...
- [洛谷P1707] 刷题比赛
洛谷题目连接:刷题比赛 题目背景 nodgd是一个喜欢写程序的同学,前不久洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题.于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家-- ...
随机推荐
- 尝试造了个工具类库,名为 Diana
项目地址: diana 文档地址: http://muyunyun.cn/diana/ 造轮子的意义 为啥已经有如此多的前端工具类库还要自己造轮子呢?个人认为有以下几个观点吧: 定制性强,能根据自己的 ...
- 在非controllers中获取httpServletRequest
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()) ...
- NanUI文档 - 打包并使用内嵌式的HTML/CSS/JS资源
NanUI文档目录 NanUI简介 开始使用NanUI 打包并使用内嵌式的HTML/CSS/JS资源 使用网页来设计整个窗口 如何实现C#与Javascript相互掉用(待更新...) 如何处理Nan ...
- idea将maven项目打包成war包的方式,以及使用war包
打包WAR过程 首先对项目进行编译.然后执行以下步骤: 单击下图红色方框处 在IDEA右侧出现maven project选项 单击maven project选项,出现Spring MVC Basi ...
- SVN 安装与使用教程总结
转载:http://www.cnblogs.com/armyfai/p/3985660.html SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需 ...
- 《英文写作指南 The elements of style》【PDF】下载
<英文写作指南 The elements of style>[PDF]下载链接: https://u253469.ctfile.com/fs/253469-231196361 The el ...
- 小白的Python之路 if __name__ == '__main__' 解析
if __name__ == '__main__' 参考文献: http://www.cnblogs.com/xuxm2007/archive/2010/08/04/1792463.html http ...
- 三菱Q系列PLC的io分配
1.系统基本配置 2.存储卡配置 3.外部IO标号 4.主基板IO模块的IO号分配 5.扩展基板IO口标号 6.标准配置实例 7. 一.输入采样阶段 在输入采样阶段,可编程逻辑控制器以扫描方式依次地读 ...
- React Native绑定微信分享/登录/支付(演示+实现步骤+注意事项)
React Native(以下简称RN)绑定微信分享/微信登录/微信支付的实现演示+源码+注意事项!微信的调用大同小异,本文实现了微信的分享功能,其他功能可以在链接文档里面找到具体的方法. 本文分文三 ...
- 搜索模式| 系列2——KMP算法
给定一个文本txt [0..n-1]和一个模式pat [0..m-1],写一个搜索函数search(char pat [],char txt []),在txt中打印所有出现的pat [] [].可以假 ...