【后缀自动机】洛谷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刷题.于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家-- ...
随机推荐
- 【Sqlserver系列】初级思维导图
1 概述 本篇文章主要概述Sqlserver思维导图. 2 具体内容 3 参考文献 [01]https://mp.weixin.qq.com/s/USNMslpvu7pWosMZnVTPd ...
- 【quickhybrid】API的分类:短期API、长期API
前言 一切就绪,开始规划API,这里在规划前对API进行了一次分类:短期API.长期API 首先申明下,这个是在实际框架演变过程中自创的一个概念,其它混合框架可能也会有这个概念,但应该是会在原生底层来 ...
- tcpdump抓包和scp导出以及wireshark查看
[命令和工具] tcpdump scp wireshark (1)tcpdump sudo tcpdump -i eth0 -w /home/tcpdump/1.pcap host 10.214.1 ...
- Java加密与解密笔记(二) 对称加密
前面的仅仅是做了编码或者摘要,下面看看真正的加密技术. DES public class DESUtil { static final String ALGORITHM = "DES&quo ...
- 停止Flink任务
1.简单粗暴 控制台中Ctrl+C 2.UI中点击"Cancel" 3.执行cancel命令,需要知道Flink的Job ID # flink cancel jobId
- ligerUI---ligerGrid分页排序的使用(从后台获取数据显示)
写在前面: 最近项目的前框框架用的是ligerUI,里面用到了ligerGrid表格,下面就来说说从后台获取数据并在前台页面进行完美展示.啊哈哈哈..(天啦,坐我旁边的丽姐貌似炒股 一个月可以搞几十万 ...
- 1_3 C语言解决求n!
求n!(n为键盘输入的任意整数值).要求分别用while语句和for语句实现 用while语句实现: #include <stdio.h> int main() { int n; scan ...
- VS源码编译QuaZip(Windows下)
最近写个Qt demo,想要使用压缩和解压多个文件的功能,并不使用额外进程.网上参考了很多资料,发现只有QuaZip比较适合我的需求.但是QuaZip只提供源码,因此需要自己来编译. QuaZip简介 ...
- 【Socket】苍老师有了丈夫,我也有了SAEA
一.前言 时间过得真是快,转眼就2018年了.首先祝各位博友,软件开发者新年新气象,事业有成,身体健康,阖家幸福!最近看到园子里好多关于自己的2017年度总结以及对自己新一年的愿景,觉得 ...
- c#发展前景
根据育龙网资料评价显示:C#几乎集中了所有关于软件开发和软件工程研究的最新成果:面向对象.类型安全.组件技术.自动内存管理.跨平台异常处理.版本控制.代码安全管理…….尽管像很多人注意到的一样,罗列上 ...