【后缀自动机】洛谷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刷题.于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家-- ...
随机推荐
- WinCE的C#编程,对float型进行四舍五入保留两位小数,小数进行四舍五入操作,Math.Round的应用案例。
private float ConvertFloat4Se5Ru(float flotValue) { int iValue = (int)Math.Round(flotV ...
- hihoCoder_二分·归并排序之逆序对
一.题目 题目1 : 二分·归并排序之逆序对 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 在上一回.上上回以及上上上回里我们知道Nettle在玩<艦これ&g ...
- Android Root原理初探
Root Linux:Root == Windows:Adminstrator Android是Linux系统吗? 操作系统 = 系统内核 + 文件系统 Linux发行版:Linux内核 + 文件系统 ...
- jersey框架实现文件上传
jersey框架是一个开源的RESTful的框架,实现了实现了JAX-RS规范,进一步地简化 RESTful service 和 client 开发.当然而且是必须的,jersey对文件的上传和下载也 ...
- 自学Zabbix3.9.3-模板Templates-嵌套Nesting
自学Zabbix3.9.3-模板Templates-嵌套Nesting 嵌套是一个模板包含一个或多个其他模板的方法.可以在一个"嵌套"模板中将一些模板链接在一起.嵌套的好处在于,只 ...
- androidstudio连接SCM Manager上的Git库
1.在SCM Manager里创建一个Git库 在androidstudio里选中从版本控制里导入 输入git库的地址,接下来一路点击下一步 完成之后会可以在工程里创建文件或者从别的地方把完整项目拷贝 ...
- 非常有用的GitHub链接
平常开发工作中,我经常取Github上搜索项目,Clone下来学习使用,在这个过程中,发现了好多比较好的Github地址,记录下来,分享出去. image 非常有用的GitHub链接(顺序不分先后): ...
- 用Azure AD 实现Web 应用身份认证的Multi-Factor Authentication(MFA)
最近客户有个需求,希望把面向public的Web应用中的终端用户数据库由Azure AD来实现,同时希望可以用MFA来实现用户身份认证.这个想法非常好,通过使用Azure的managed servic ...
- [array] leetcode - 33. Search in Rotated Sorted Array - Medium
leetcode - 33. Search in Rotated Sorted Array - Medium descrition Suppose an array sorted in ascendi ...
- strtus2中的default-action-ref无效的解决方法
strtus2中的default-action-ref的作用是我们在浏览器中访问错误的地址时可以跳转到自己设置的错误页面,而不是令人尴尬的系统错误页面,这个系统错误很常见,就是提示在namespace ...