【后缀自动机】洛谷P3804模板题

时间:2022-09-10 20:12:26

题目描述

给定一个只包含小写字母的字符串S,

请你求出 S 的所有出现次数不为 1 的子串的出现次数乘上该子串长度的最大值。

输入输出格式

输入格式:

一行一个仅包含小写字母的字符串S

输出格式:

一个整数,为 所求答案

输入输出样例

输入样例#1:
abab
输出样例#1:
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模板题的更多相关文章

  1. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  2. 【后缀数组】洛谷P3809模板题

    题目背景 这是一道模板题. 题目描述 读入一个长度为 n n n 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...

  3. 【最大流ISAP】洛谷P3376模板题

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  4. 洛谷 P3804 &lbrack;模板&rsqb; 后缀自动机

    题目:https://www.luogu.org/problemnew/show/P3804 模仿了一篇题解,感觉很好写啊. 代码如下: #include<cstdio> #include ...

  5. LCA算法倍增算法(洛谷3379模板题)

    倍增(爬树)算法,刚刚学习的算法.对每一个点的父节点,就记录他的2k的父亲. 题目为http://www.luogu.org/problem/show?pid=3379 第一步先记录每一个节点的深度用 ...

  6. 洛谷 P4148 简单题 KD-Tree 模板题

    Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...

  7. 洛谷P3373 &lbrack;模板&rsqb;线段树 2&lpar;区间增减&period;乘 区间求和&rpar;

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  8. 【noip】跟着洛谷刷noip题2

    noip好难呀. 上一个感觉有点长了,重开一个. 36.Vigenère 密码 粘个Openjudge上的代码 #include<cstdio> #include<iostream& ...

  9. &lbrack;洛谷P1707&rsqb; 刷题比赛

    洛谷题目连接:刷题比赛 题目背景 nodgd是一个喜欢写程序的同学,前不久洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题.于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家-- ...

随机推荐

  1. chinapay

    http://s.yanghao.org/program/viewdetail.php?i=71959 http://www.codeproject.com/csharp/biginteger.asp ...

  2. Linux批量替换文件内容

    问题描述:现在需要将rack1目录下*.send文件中的"-ip="替换成“-localIp=10.0.0.1/n-ip=” 刚才那个批量文本内容替换,只能替换内存中的内容,并不会 ...

  3. css案例学习之全局声明&ast;&lbrace;&rcub; 与body&lbrace;&rcub;的区别

    代码 <html> <head> <title>全局声明</title> <style type="text/css"> ...

  4. NSURLRequest POST方式请求服务器示例

    http://lizhuang.iteye.com/blog/1833297 1.  准备阶段 NSString *urlString = [NSString stringWithFormat:@&q ...

  5. &lbrack;翻译&rsqb; 比较 Node&period;js,Python,Java,C# 和 Go 的 AWS Lambda 性能

    [翻译] 比较 Node.js,Python,Java,C# 和 Go 的 AWS Lambda 性能 原文: Comparing AWS Lambda performance of Node.js, ...

  6. 解决 Scrapy-Redis 空跑问题,链接跑完后自动关闭爬虫

    Scrapy-Redis 空跑问题,redis_key链接跑完后,自动关闭爬虫 问题:scrapy-redis框架中,reids存储的xxx:requests已经爬取完毕,但程序仍然一直运行,如何自动 ...

  7. Linux使用 tar命令-g参数进行增量&plus;差异备份、还原文件

    原文链接:http://www.cnblogs.com/gnuhpc/ 完整备份: 建立测试路径与档案 mkdir test touch test/{a,b,c} 在test下生成三个文件 执行完整备 ...

  8. thinkphp 5&period;0手记

    场景配置,可配置多个数据库,按需求加载 数组合并:array_merge();键名相同后面覆盖前面 array_merge_recursive();键名相同,键值合并 对与http://localho ...

  9. Fiddler进行模拟Post提交json数据,总为null解决方式(转)

    原文链接:http://www.cnblogs.com/jys509/p/3550598.html Request Headers: User-Agent: FiddlerHost: localhos ...

  10. MongoDB shell基本操作

    shell命令操作语法和JavaScript很类似,其实控制台底层的查询语句都是用JavaScript脚本完成操作的.使用shell 命令,需要启动mongo.exe.mongodb百科 常用shel ...