CodeForces700E Cool Slogans
感谢dalaoWJZ的讲解。
我们对于每一个串a[i]相当于在他parent的right集合里找一个出现位置在id-len[x]+len[parent]到id[x]-1区间的
用主席树判存在性即可。
至于我问了很久这个区间为什么不能往前判,原因是你每个节点都代表唯一一个子串,所以我们定性查询就可以啦。
By:大奕哥
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+;
int rt[N],num,n;
char s[N];
struct tree{
int l,r;
}t[N*];
void change(int &x,int l,int r,int p)
{
if(!x)x=++num;
if(l==r)return;
int mid=l+r>>;
if(p>mid)change(t[x].r,mid+,r,p);
else change(t[x].l,l,mid,p);
}
void merge(int &x,int y)
{
if(!x||!y){x=x+y;return;}
++num;t[num]=t[x];x=num;
merge(t[x].l,t[y].l);
merge(t[x].r,t[y].r);
}
bool query(int x,int l,int r,int L,int R)
{
if(!x)return ;
if(l==L&&r==R)return ;
int mid=l+r>>;
if(mid<L)return query(t[x].r,mid+,r,L,R);
else if(mid>R)return query(t[x].l,l,mid,L,R);
else return query(t[x].l,l,mid,L,mid)|query(t[x].r,mid+,r,mid+,R);
}
struct SAM
{
int cnt,root,last,c[N][],f[N],dp[N],tt[N],pos[N],r[N],id[N],l[N];
SAM(){cnt=;last=root=++cnt;}
void add(int x,int dd)
{
int now=last,a=++cnt;last=a;id[a]=dd;
l[a]=l[now]+;
for(;now&&!c[now][x];now=f[now])c[now][x]=a;
if(!now)f[a]=root;
else{
int q=c[now][x];
if(l[q]==l[now]+)f[a]=q;
else{
int b=++cnt;id[b]=dd;
l[b]=l[now]+;
f[b]=f[q];
f[a]=f[q]=b;
memcpy(c[b],c[q],sizeof(c[q]));
for(;now&&c[now][x]==q;now=f[now])c[now][x]=b;
}
}
return;
}
void sort(){
for(int i=;i<=cnt;++i)tt[l[i]]++;
for(int i=;i<=n;++i)tt[i]+=tt[i-];
for(int i=;i<=cnt;++i)r[tt[l[i]]--]=i;
return;
}
void work()
{
for(int i=cnt;i>=;--i)
{
int x=r[i];
change(rt[x],,n,id[x]);
merge(rt[f[x]],rt[x]);
}int ans=;
for(int i=;i<=cnt;++i)
{
int x=r[i];
if(f[x]==){pos[x]=x,dp[x]=;continue;}
if(query(rt[pos[f[x]]],,n,id[x]-l[x]+l[pos[f[x]]],id[x]-))
dp[x]=dp[pos[f[x]]]+,pos[x]=x;
else dp[x]=dp[pos[f[x]]],pos[x]=pos[f[x]];
ans=max(ans,dp[x]);
}
printf("%d\n",ans);
return;
}
}A;
int main()
{
scanf("%d%s",&n,s+);
for(int i=;i<=n;++i)A.add(s[i]-'a',i);
A.sort();A.work();
return ;
}
CodeForces700E Cool Slogans的更多相关文章
- 题解-CodeForces700E Cool Slogans
Problem 题目链接 题目大意:给定一个字符串,每次取出出现至少两次的子串替换原串,问最多能替换多少次,输出答案加一(字符串长为\(2×10^5\)) Solution 前置技能:SAM.线段树合 ...
- CF700E Cool Slogans
CF700E Cool Slogans 题目描述 给出一个长度为n的字符串\(s[1]\),由小写字母组成.定义一个字符串序列\(s[1....k]\),满足性质:\(s[i]\)在\(s[i-1] ...
- 【CF700E】Cool Slogans 后缀自动机+线段树合并
[CF700E]Cool Slogans 题意:给你一个字符串S,求一个最长的字符串序列$s_1,s_2,...,s_k$,满足$\forall s_i$是S的子串,且$s_i$在$s_{i-1}$里 ...
- CF 700 E. Cool Slogans
E. Cool Slogans 链接 题意: 给定一个字符串S,从中选出k个子串a[1],a[2]...a[k],满足a[i]在a[i+1]中出现了两次(可以重叠),求最大的k. 分析: 建出SAM, ...
- 【CF700E】Cool Slogans(后缀自动机)
[CF700E]Cool Slogans(后缀自动机) 题面 洛谷 CodeForces 题解 构建后缀自动机,求出后缀树 现在有个比较明显的\(dp\) 设\(f[i]\)表示从上而下到达当前点能够 ...
- [LOJ 6288]猫咪[CF 700E]Cool Slogans
[LOJ 6288]猫咪[CF 700E]Cool Slogans 题意 给定一个字符串 \(T\), 求一个最大的 \(K\) 使得存在 \(S_1,S_2,\dots,S_k\) 满足 \(S_1 ...
- Codeforces 700E. Cool Slogans
Description 给定一个串 \(S\),求一个序列 \(a_i\),满足 \(a_i\) 是原串的子串,且 \(a_i\) 在 \(a_{i-1}\) 中至少出现两次,求这个序列的最大的长度 ...
- CF700E E. Cool Slogans
https://codeforces.com/contest/700/problem/E 题解:https://www.luogu.org/problemnew/solution/CF700E 其实就 ...
- Codeforces 700E. Cool Slogans 字符串,SAM,线段树合并,动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF700E.html 题解 首先建个SAM. 一个结论:对于parent树上任意一个点x,以及它所代表的子树内任 ...
随机推荐
- java字符数组char[]和字符串String之间的转换
java字符数组char[]和字符串String之间的转换 觉得有用的话,欢迎一起讨论相互学习~Follow Me 使用String.valueOf()将字符数组转换成字符串 void (){ cha ...
- js 隐藏代码生成工具
昨天写了篇<js 奇葩技巧之隐藏代码>,今天来写个工具方便大家生成吧.在昨天算法基础上优化了解码算法,采用立即函数运行.有两种模式可供选择: 1. eval 全局模式,比如你定义的 va ...
- 20155210潘滢昊 2016-2017-2 《Java程序设计》第8周学习总结
20155210 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 认识NIO Channel: 衔接数据节点(与IO中的流对比) isOpen close R ...
- 关于Hadoop未授权访问可导致数据泄露通知
尊敬的腾讯云客户: 您好!近日,外部媒体报道全球Hadoop服务器因配置不安全导致海量数据泄露,涉及使用Hadoop分布式文件系统(HDFS)的近4500台服务器,数据量高达5120 TB (5.12 ...
- linux动态追踪神器——Strace实例介绍【转】
Strace是Linux下一款通用的进程动态跟踪工具,用来追踪程序执行时的系统调用和所接收的信号.其应用方法如下图(部分). 首先,简单说说它的使用参数,Strace的参数包括输出参数.过滤参数.统计 ...
- .net的锁
一.lock .Monitor 处理并行任务的时候,效率最高的就是多线程.当不同线程需要访问同一资源时候,就需要同步了.就像生活中很多人要一起赶飞机大家都要访问飞机这个资源每个人是一条线程那么就有门 ...
- 计算机底层知识拾遗(九)深入理解内存映射mmap
内存映射mmap是Linux内核的一个重要机制,它和虚拟内存管理以及文件IO都有直接的关系,这篇细说一下mmap的一些要点. 修改(2015-11-12):Linux的虚拟内存管理是基于mmap来实现 ...
- java LinkedList(链表)
LinkedList也像ArrayList一样实现了基本的List接口,但是它执行某些操作(在List的中间插入和移除)时比ArrayList更高效,但在随机访问方面却要逊色一些 LinkedList ...
- 和为k的最长子数组及其延伸
问题1: /** * 问题描述: * 给定一个无序数组arr,其中元素可正.可负.可0, * 求arr所有的子数组中正数与负数个数相等的最长子数组长度 * * 解题思路:对数组进行处理,正数为1,负数 ...
- interface关键字定义接口
package interface0; public interface InterfaceTest { /* * 接口的定义,使用interface关键字定义接口 */ public interfa ...