Codeforces 700E. Cool Slogans
Description
给定一个串 \(S\),求一个序列 \(a_i\),满足 \(a_i\) 是原串的子串,且 \(a_i\) 在 \(a_{i-1}\) 中至少出现两次,求这个序列的最大的长度
题面
Solution
根据后缀自动机的性质可以做,首先建出 \(parent\) 树,然后满足条件的序列一定是树上的一条链去掉一些节点
然后就是需要满足出现两次的要求了:
因为是祖先关系,所以至少出现了一次,设 \(pos[i]\) 表示节点 \(i\) 所接受的子串都是以原串中 \(pos[i]\) 这个位置结尾的
另外一次我们就找到这个子串在原串中所代表的区间:\([pos[x]-(len[x]-len[fa[x]]),pos[x]]\),如果这个节点在某个儿子节点所代表的区间中出现了两次,那么就符合要求了
我们用线段树维护 \(pos\) 集合就行了,我们从下往上线段树合并就行了
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int n,ch[N][26],fa[N],cur=1,cnt=1,len[N],b[N],f[N],ans=0;char s[N];
int pos[N],rt[N],ls[N*30],rs[N*30],tt=0,head[N],nxt[N],to[N],num=0;
inline void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
inline void Modify(int &x,int l,int r,int sa){
if(!x)x=++tt;
if(l==r)return ;
int mid=(l+r)>>1;
if(sa<=mid)Modify(ls[x],l,mid,sa);
else Modify(rs[x],mid+1,r,sa);
}
inline void ins(int c){
int p=cur;cur=++cnt;len[cur]=len[p]+1;
for(;p && !ch[p][c];p=fa[p])ch[p][c]=cur;
if(!p)fa[cur]=1;
else{
int q=ch[p][c];
if(len[p]+1==len[q])fa[cur]=q;
else{
int nt=++cnt;len[nt]=len[p]+1;
memcpy(ch[nt],ch[q],sizeof(ch[nt]));
fa[nt]=fa[q];fa[q]=fa[cur]=nt;
for(;p && ch[p][c]==q;p=fa[p])ch[p][c]=nt;
}
}
}
inline int merge(int x,int y){
if(!x || !y)return x+y;
int c=++tt;
ls[c]=merge(ls[x],ls[y]);
rs[c]=merge(rs[x],rs[y]);
return c;
}
inline void dfs(int x){
for(int i=head[x];i;i=nxt[i]){
dfs(to[i]),rt[x]=merge(rt[x],rt[to[i]]);
if(!pos[x])pos[x]=pos[to[i]];
}
}
inline bool qry(int x,int l,int r,int sa,int se){
if(!x)return false;
if(sa<=l && r<=se)return true;
int mid=(l+r)>>1;
if(se<=mid)return qry(ls[x],l,mid,sa,se);
if(sa>mid)return qry(rs[x],mid+1,r,sa,se);
return qry(ls[x],l,mid,sa,mid)|qry(rs[x],mid+1,r,mid+1,se);
}
inline void dfs1(int x){
for(int i=head[x],t,u;i;i=nxt[i]){
u=to[i];
t=qry(rt[b[x]],1,n,pos[u]-len[u]+len[b[x]],pos[u]-1);
if(t)f[u]=f[x]+1,b[u]=u;
else f[u]=f[x],b[u]=b[x];
dfs1(u);
}
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
scanf("%d%s",&n,s+1);
for(int i=1;i<=n;i++)
ins(s[i]-'a'),pos[cur]=i,Modify(rt[cur],1,n,i);
for(int i=2;i<=cnt;i++)link(fa[i],i);
dfs(1);
for(int i=head[1];i;i=nxt[i])b[to[i]]=to[i],f[to[i]]=1,dfs1(to[i]);
for(int i=2;i<=cnt;i++)ans=max(ans,f[i]);
printf("%d\n",ans);
return 0;
}
Codeforces 700E. Cool Slogans的更多相关文章
- Codeforces 700E. Cool Slogans 字符串,SAM,线段树合并,动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF700E.html 题解 首先建个SAM. 一个结论:对于parent树上任意一个点x,以及它所代表的子树内任 ...
- Codeforces.700E.Cool Slogans(后缀自动机 线段树合并 DP)
题目链接 \(Description\) 给定一个字符串\(s[1]\).一个字符串序列\(s[\ ]\)满足\(s[i]\)至少在\(s[i-1]\)中出现过两次(\(i\geq 2\)).求最大的 ...
- [LOJ 6288]猫咪[CF 700E]Cool Slogans
[LOJ 6288]猫咪[CF 700E]Cool Slogans 题意 给定一个字符串 \(T\), 求一个最大的 \(K\) 使得存在 \(S_1,S_2,\dots,S_k\) 满足 \(S_1 ...
- SA / SAM 题目集
上一次做 SA / SAM 相关的题还要数到某场毒瘤 NOIP 模拟赛--这么久没做了都快忘光了--写点东西记录一些最近做到的水好题. LOJ2059 「TJOI / HEOI2016」字符串 题意 ...
- 【CF700E】Cool Slogans(后缀自动机)
[CF700E]Cool Slogans(后缀自动机) 题面 洛谷 CodeForces 题解 构建后缀自动机,求出后缀树 现在有个比较明显的\(dp\) 设\(f[i]\)表示从上而下到达当前点能够 ...
- Codeforces 1063F - String Journey(后缀数组+线段树+dp)
Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
随机推荐
- 《Effective Objective-C 2.0》摘要
前一段时间将<Effective Objective-C 2.0>这本书浏览了一遍,说一下几个觉得比较有意思的知识点. 感觉这本书是ios开发必看的一本书,最基础的,以及稍微高阶一点的oc ...
- 团队作业4——第一次项目冲刺(Alpha版本)11.14
a. 提供当天站立式会议照片一张 举行站立式会议,讨论项目安排: PM对整个项目的需求进行讲解: 全队对整个项目的细节进行沟通: 对整个项目的开发计划进行分析,分配每天的任务: 统一确定项目的开发环境 ...
- DML数据操作语言之增加,删除,更新
1.数据的增加 数据的增加要用到insert语句 ,基本格式是: insert into <表名> (列名1,列名2,列名3,......) values (值1,值2,值3,..... ...
- URL编码和Base64编码 (转)
我们经常会遇到所谓的URL编码(也叫百分号编码)和Base64编码. 先说一下Bsae64编码.BASE64编码是一种常用的将二进制数据转换为64个可打印字符的编码,常用于在通常处理文本数据 ...
- Tomcat性能优化及JVM内存工作原理
Java性能优化原则:代码运算性能.内存回收.应用配置(影响Java程序主要原因是垃圾回收,下面会重点介绍这方面) 代码层优化:避免过多循环嵌套.调用和复杂逻辑. Tomcat调优主要内容如下: 1. ...
- Angular组件——父组件调用子组件方法
viewChild装饰器. 父组件的模版和控制器里调用子组件的API. 1.创建一个子组件child1里面只有一个greeting方法供父组件调用. import { Component, OnIni ...
- 修改了SpringBoot的主类名称后,gradle build报错的解决办法
Unable to find a single main class from the following candidates [*.*Application]
- Angular 学习笔记 ( 链接服务器 )
ng 是做前端开发的, 所以通常我们会配上一个 API server. 本地调试时通常使用 proxy https://github.com/angular/angular-cli/blob/mast ...
- redis入门(02)redis的常见问题
一.常见问题 1.安装遇到/bin/sh: cc: command not found 解决办法:安装gcc yum install gcc 2.后台启动server端 2.1.问题现象 2.2.解决 ...
- IDE-Android Studio -FAQ-使用习惯(不断更新 欢迎留言)
摘要: 从ecplise工具切换到android studio后遇到了很多问题,起初亦非常痛苦,城墙内外阅博无数才得以解决.所以把当时遇到的问题记录下来,方便后来人学习. 另如果有遇到未纪录的问题欢迎 ...