题解-CodeForces700E Cool Slogans
Problem
题目大意:给定一个字符串,每次取出出现至少两次的子串替换原串,问最多能替换多少次,输出答案加一(字符串长为\(2×10^5\))
Solution
前置技能:SAM、线段树合并、dp
首先可以想到一个dp(设t为在s中出现至少两次的子串):\(dp[s]=\max\{dp[t] \}+1\)
然后想到如果t在s中出现不止一次,则在考虑t时,要求在s的endpos集合中一定存在一个处于区间\(\bigl[t_{longest}+s_{pos}-s_{longest},s_{longest}\bigr )\)的endpos,至于求endpos可以使用线段树合并求解
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rg register
const int N=401000,M=8001000;
int stp[N],ch[N][26],pre[N],pos[N],top[N],rt[N];
int ls[M],rs[M],b[N],f[N],tpy[N];
int n,tot=1,cnt,Ans=1,lst=1;
char s[N];
inline void ins(int x){
int p=lst,np=++tot;
lst=tot;stp[np]=stp[p]+1;
while(p&&!ch[p][x])ch[p][x]=np,p=pre[p];
if(!p)pre[np]=1;
else {
int q=ch[p][x];
if(stp[q]==stp[p]+1)pre[np]=q;
else {
int nq=++tot;stp[nq]=stp[p]+1;pos[nq]=pos[q];
for(rg int i=0;i<26;++i)ch[nq][i]=ch[q][i];
pre[nq]=pre[q];pre[q]=pre[np]=nq;
while(ch[p][x]==q)ch[p][x]=nq,p=pre[p];
}
}return ;
}
inline int merge(int u,int v){
if(!u||!v)return u+v;
int z=++cnt;
ls[z]=merge(ls[u],ls[v]);
rs[z]=merge(rs[u],rs[v]);
return z;
}
inline void update(int l,int r,int&x,int al){
if(!x)x=++cnt;
if(l==r)return ;
int mid(l+r>>1);
if(al<=mid)update(l,mid,ls[x],al);
else update(mid+1,r,rs[x],al);
return ;
}
inline int query(int l,int r,int x,int L,int R){
if(!x)return 0;
if(L<=l&&r<=R)return 1;
int mid(l+r>>1),res(0);
if(L<=mid)if(query(l,mid,ls[x],L,R))return 1;
if(mid<R)if(query(mid+1,r,rs[x],L,R))return 1;
return 0;
}
int main(){
scanf("%d%s",&n,s+1);
for(rg int i=1;i<=n;++i){ins(s[i]-'a');update(1,n,rt[lst],i);pos[lst]=i;}
for(rg int i=1;i<=tot;++i)++b[stp[i]];
for(rg int i=1;i<=n;++i)b[i]+=b[i-1];
for(rg int i=tot;i;--i)tpy[b[stp[i]]--]=i;
for(rg int i=tot;i^1;--i)rt[pre[tpy[i]]]=merge(rt[pre[tpy[i]]],rt[tpy[i]]);
for(rg int i=2;i<=tot;++i){
int x(tpy[i]),fa(pre[x]);
if(fa==1){f[x]=1,top[x]=x;continue;}
if(query(1,n,rt[top[fa]],pos[x]-(stp[x]-stp[top[fa]]),pos[x]-1))f[x]=f[fa]+1,top[x]=x;
else f[x]=f[fa],top[x]=top[fa];
Ans=max(Ans,f[x]);
}printf("%d\n",Ans);return 0;
}
题解-CodeForces700E Cool Slogans的更多相关文章
- CodeForces700E Cool Slogans
感谢dalaoWJZ的讲解. 我们对于每一个串a[i]相当于在他parent的right集合里找一个出现位置在id-len[x]+len[parent]到id[x]-1区间的 用主席树判存在性即可. ...
- 【CF700E】Cool Slogans 后缀自动机+线段树合并
[CF700E]Cool Slogans 题意:给你一个字符串S,求一个最长的字符串序列$s_1,s_2,...,s_k$,满足$\forall s_i$是S的子串,且$s_i$在$s_{i-1}$里 ...
- 【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 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
随机推荐
- Linux记录-jstack采集namenode堆栈信息
#!/bin/bash #以hdfs用户执行jstack每分钟采集一次namenode heapstack日志 #mkdir -p /tmp/jstack export JAVA_HOME=/app/ ...
- java和c#通过esb服务互调用组件
场景:java和c#写的服务.站点,互相任意调用.实现一切即服务. 解决方案:使用这种轻量级的esb架构,通过tcp通信解决通信传输问题,总线服务解决服务地址问题,契约解决数据交互问题.由于组件封装了 ...
- android studio导出apk
在android studio导出的apk分为4种,一种是未签名调试版apk,一种是未签名发行版apk,一种是已签名调试版apk,还有一种是已签名发行版apk.以下将介绍这4种apk如何导出. 一.调 ...
- React 记录(1)
作为一个前端工程师,前端框架是必须会的,所以开始学习React. 学习的方法是:先实践,后图文记录. React官网:https://reactjs.org React中文网站:https://www ...
- DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区
前言 由于在Direct3D 11中取消了固定管线,要想绘制图形必须要了解可编程渲染管线的流程,一个能绘制出图形的渲染管线最少需要有这两个可编程着色器:顶点着色器和像素着色器. 本章会直接跳过渲染管线 ...
- JQ和Js获取span标签的内容
JQ和Js获取span标签的内容 html: 1 <span id="content">‘我是span标签的内容’</span> javascript获取: ...
- spring中获取dao或对象中方法的实例化对象
spring中获取dao的中方法的实例化对象: //获取应用上下文对象 ApplicationContext ctx = new ClassPathXmlApplicationContext(&quo ...
- 二叉树的python可视化和常用操作代码
二叉树是一个重要的数据结构, 本文基于"二叉查找树"的python可视化 pybst 包, 做了一些改造, 可以支持更一般的"二叉树"可视化. 关于二叉树和二叉 ...
- JS创建对象之动态原型模式
动态原型模式把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),又保持了 同时使用构造函数和原型的优点:换句话说,可以通过检查某个应该存在的方法是否有效,来决定是否需要初 ...
- Android开发最强模拟器Genymotion的安装及使用教程。附注释图详解
前沿 呵呵,笔者第一次在公开的博客网站写心得,想让自己的Android开发生涯留下点足迹,并且为自己做点笔记,如果该文章能帮到广大的Android小白朋友最好了(其实我也是一小白,(●'◡'●)) ...