• 源自 xyz32768 菜鸡的 FJ 省冬令营模拟赛题

  • 原题 CF1063F

Statement

  • 给定一个长度为 \(n\) 的字符串 \(s\),仅包含小写英文字母

  • 要从中从左往右选出若干段不相交的子串

  • 使得选出的这些串中,每个串都是上一个串的严格子串

  • 求最多能选出多少段

  • \(1\le n\le5\times10^5\)

Solution

  • 首先注意到一个性质:设选出的第一个子串长度为 \(len\),那么最优解选出的子串长度一定是 \(len,len-1,\dots,2,1\)

  • 于是从右往左 DP:\(f[i][j]\) 表示以 \(i\) 为首串的开头,是否存在选出 \(j\) 段的方案(也是首串的长度为 \(j\))

  • 这个 DP 是 \(O(n^2)\) 的

  • 我们还有一个性质:\(f[i][j]\) 是单调的。换句话说,如果存在选出 \(j\) 个串的方案就一定存在选出 \(j-1\) 个串的方案

  • 证明考虑第一个串 \(t\) ,如果选出的前 \(k\) 个串都是 \(t\) 的后缀,而第 \(k+1\) 个串是第 \(k\) 个串的前缀,那么我们可以把前 \(k\) 个串都删掉最后一个字符,第 \(k+1\) 个串直接扔掉,这样就构造出了一个选 \(j-1\) 个串的方案,特殊情况 \(k=j\) 时把所有串都删掉最后一个字符并把最后一个串(长度已经变成 \(0\))扔掉

  • 于是可以重新定义 \(f[i]\) 表示以 \(i\) 为开头最多选出多少个串

  • 根据上面的结论,可以二分 \(f[i]\),转化成判断是否存在 \(j\in[i+f[i]\dots n]\) 使得 \(\max(\text{lcp}(i,j),\text{lcp}(i+1,j))\ge f[i]-1\) 且 \(f[j]\ge f[i]-1\)

  • 易得建出 SA 之后,满足 \(\text{lcp}(i,j)\ge f[i]-1\) 的 \(rank_j\) 是一段区间,可以二分 + RMQ 求出这个区间之后,利用可持久化线段树求得该区间内的 \(f[j]\) 最大值,\(\text{lcp}(i+1,j)\) 同理

  • 这样的复杂度是 \(O(n\log^2n)\) 的

  • 注意到另一个性质:\(f[i+1]\ge f[i]-1\),证明类似上一个结论

  • 于是把 \(f[i]\) 设成 \(f[i+1]+1\) 之后不断检查当前的 \(f[i]\) 是否合法,如果不合法就一直 \(f[i]--\)

  • 易得 \(f[i]--\) 的次数之和不超过 \(O(n)\),所以总复杂度 \(O(n\log n)\)

  • 现场 \(O(n\log^2n)\) 甚至 \(O(n\sqrt n)\) 小常数过了,声名狼藉 QAQ

Code

  • 咕咕咕

[DP][SA][可持久化线段树]黑红兔的更多相关文章

  1. BZOJ5371[Pkusc2018]星际穿越——可持久化线段树+DP

    题目描述 有n个星球,它们的编号是1到n,它们坐落在同一个星系内,这个星系可以抽象为一条数轴,每个星球都是数轴上的一个点, 特别地,编号为i的星球的坐标是i. 一开始,由于科技上的原因,这n个星球的居 ...

  2. 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)

    有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...

  3. 【CF768G】The Winds of Winter 可持久化线段树 DFS序

    题目大意 给定一棵\(n\)个点的树,对于树上每个结点,将它删去,然后可以将得到的森林中任意一个点与其父亲断开并连接到另一颗树上,对每一个点求出森林中所有树\(size\)最大值的最小值. \(n\l ...

  4. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  5. BZOJ 4408: [Fjoi 2016]神秘数 可持久化线段树

    4408: [Fjoi 2016]神秘数 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4408 Description 一个可重复数字集 ...

  6. 2018-8-10 模拟赛T3(可持久化线段树)

    出题人说:正解离线按DFS序排序线段维护区间和 但是对于树上每个点都有一个区间和一个值,两个点之间求1~m的区间和,这不就是用可持久化线段树吗. 只不过这个线段树需要区间修改,不过不需要标记下传,询问 ...

  7. BZOJ 4556(后缀数组+主席树求前驱后继+二分||后缀数组+二分+可持久化线段树)

    换markdown写了.. 题意: 给你一个1e5的字符串,1e5组询问,求\([l_1,r_1]\)的所有子串与\([l_2,r_2]\)的lcp 思路: 首先可以发现答案是具有单调性的,我们考虑二 ...

  8. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  9. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

随机推荐

  1. jquery监听输入框只能输入数字

    $('#mm').bind('input propertychange',function(){ var val= $(this).val(); if(val!=''&& isNaN( ...

  2. C# 字典 Dictionary 的 TryGetValue 与先判断 ContainsKey 然后 Get 的性能对比

    本文使用 benchmarkdotnet 测试字典的性能,在使用字典获取一个可能存在的值的时候可以使用两个不同的写法,于是本文分析两个写法的性能. 判断值存在,如果值存在就获取值,可以使用下面两个不同 ...

  3. codeforces 1194F (组合数学)

    Codeforces 11194F (组合数学) 传送门:https://codeforces.com/contest/1194/problem/F 题意: 你有n个事件,你需要按照1~n的顺序完成这 ...

  4. CITRIX ADC配置SSL卸载

    如上图,将ssl的加密解密放在前端的负载均衡设备上,客户端到VPX的访问都是加密的,VPX到后端的服务器都是http的 Step1:上传证书到VPX,如下图: Step2:创建SSL的虚拟服务器并且绑 ...

  5. Team Foundation Server 2015使用教程【6】:新增权限为读取器的团队

  6. jdbc的URL配置

    Microsoft SQL ServerMicrosoft SQL Server JDBC Driver (一般用来连接 SQLServer 2000)驱动程序包名:msbase.jar mssqls ...

  7. JMeter Webservice API测试计划

    Web Services Web服务被定义为旨在通过网络支持两台机器之间交互的软件系统.它被设计为具有以通常在Web服务描述语言(WSDL)中指定的机器可处理格式描述的接口. 通常,“HTTP”是最常 ...

  8. 记录我的 python 学习历程-Day11 两个被忽视的坑、补充知识点、函数名的应用、新版格式化输出、迭代器

    补充知识点 函数形参中默认参数的陷阱 针对不可变数据类型,它是没有陷阱的 def func(name, sex='男'): print(name) print(sex) func('Dylan') # ...

  9. dWebpack编译速度优化实战

    当你的应用的规模还很小时,你可能不会在乎Webpack的编译速度,无论使用3.X还是4.X版本,它都足够快,或者说至少没让你等得不耐烦.但随着业务的增多,嗖嗖嗖一下项目就有上百个组件了,也是件很简单的 ...

  10. __FILE__,__LINE__,__DATE__,__TIME__,__FUNCTION__的使用

    C/C++ 有5个常用的预定义宏,可以当作变量直接使用 __FILE__,__FUNCTION __,__LINE__,__DATE__,__TIME__. 注意是两个下划线. 其含义如下: __FI ...