BZOJ 3238 差异

看这个式子其实就是求任意两个后缀的 $ LCP $ 长度和。前面的 $ len(T_i)+len(T_j) $ 求和其实就是 $ n(n-1)(n+1)/2 $ ,这个是很好推的。。

任意两个后缀的 $ LCP $ 长度和很容易想到构造 height 数组,然后问题就变成了所有区间的最小值的和。

这是个套路题,可以单调栈,但是其实分治也很好写!

设我们要求的区间是 $ [l,r] $ 我们可以找出其中最小值所在的位置,这个可以ST表快速求,然后从这个位置进行分治。

这样的分治每进行一次,总有效的元素数量会减少1,因此复杂度是 $ O(nlogn) $ 的。

开始有个地方漏了 1ll 。。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 500006
#define C 130
namespace wtf {
char ch[MAXN];
int sa[MAXN], tp[MAXN], rnk[MAXN], buc[MAXN], len;
int P[MAXN][20], ht[MAXN]; int que(int l, int r) {
int L = (31 - __builtin_clz(r - l + 1));
return (ht[P[l][L]] < ht[P[r - (1 << L) + 1][L]] ? P[l][L] : P[r - (1 << L) + 1][L]);
} void init() {
len = strlen(ch + 1);
int m = C;
for (int i = 1; i <= len; ++i) ++buc[rnk[i] = ch[i]];
for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1];
for (int i = len; i >= 1; --i) sa[buc[rnk[i]]--] = i;
for (int k = 1, p = 0; p < len; k <<= 1) {
p = 0;
for (int i = 0; i <= m; ++i) buc[i] = 0;
for (int i = len - k + 1; i <= len; ++i) tp[++p] = i;
for (int i = 1; i <= len; ++i) if (sa[i] > k) tp[++p] = sa[i] - k;
for (int i = 1; i <= len; ++i) ++buc[rnk[i]];
for (int i = 1; i <= m; ++i) buc[i] += buc[i - 1];
for (int i = len; i >= 1; --i) sa[buc[rnk[tp[i]]]--] = tp[i];
p = 1;
swap(rnk, tp);
rnk[sa[1]] = 1;
for (int i = 2; i <= len; ++i)
rnk[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + k] == tp[sa[i - 1] + k]) ? p : ++p;
m = p;
}
for (int i = 1; i <= len; ++i) rnk[sa[i]] = i;
for (int i = 1, k = 0; i <= len; ++i) {
if (k) --k;
while (ch[i + k] == ch[sa[rnk[i] - 1] + k]) ++k;
ht[rnk[i]] = k;
P[i][0] = i;
}
ht[0] = 0x3f3f3f3f;
for (int i = 1; i < 20; ++i)
for (int j = 1; j <= len - (1 << i) + 1; ++j)
P[j][i] = (ht[P[j][i - 1]] < ht[P[j + (1 << i - 1)][i - 1]] ? P[j][i - 1] : P[j + (1 << i - 1)][i - 1]); } long long res = 0; void div(int l, int r) {
if( l > r ) return;
int ps = que( l , r );
res += 1ll * ht[ps] * ( ps - l + 1 ) * ( r - ps + 1 );
div( l , ps - 1 ) , div( ps + 1 , r );
} void main() {
// freopen("1.in","r",stdin);
scanf("%s", ch + 1);
init();
div( 1 , len );
cout << 1ll * ( len - 1 ) * ( len + 1 ) * len / 2 - 2 * res << endl;
}
}
int main() {
wtf::main();
}

BZOJ 3238 差异的更多相关文章

  1. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  2. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

  3. bzoj 3238 Ahoi2013 差异

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2357  Solved: 1067[Submit][Status ...

  4. BZOJ 3238: [Ahoi2013]差异 [后缀自动机]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2512  Solved: 1140[Submit][Status ...

  5. 【BZOJ 3238】 3238: [Ahoi2013]差异(SAM)

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3047  Solved: 1375 Description In ...

  6. bzoj 3238: [Ahoi2013]差异 -- 后缀数组

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...

  7. ●BZOJ 3238 [Ahoi2013]差异

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3238 题解: 后缀数组套路深. 问题转化为求出任意两个后缀的LCP之和 在计算贡献时,各种不 ...

  8. 洛谷 P4248: bzoj 3238: [AHOI2013]差异

    题目传送门:洛谷 P4248. 题意简述: 定义两个字符串 \(S\) 和 \(T\) 的差异 \(\operatorname{diff}(S,T)\) 为这两个串的长度之和减去两倍的这两个串的最长公 ...

  9. BZOJ 3238 [Ahoi2013]差异(后缀自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3238 [题目大意] 给出一个串,设T[i]表示从第i位开始的后缀, 求sum(len( ...

随机推荐

  1. 初始CSS01

    CSS基础知识 CSS介绍 CSS全称为层叠样式表,与HTML相辅相成,实现网页的排版布局与样式美化. 使用方式 根据样式表在页面中呈现的方式不同,可以通过以下三种方式在页面中使用格式 内联样式 改样 ...

  2. 【数据结构与算法Python版学习笔记】图——强连通分支

    互联网 我们关注一下互联网相关的非常巨大图: 由主机通过网线(或无线)连接而形成的图: 以及由网页通过超链接连接而形成的图. 网页形成的图 以网页(URI作为id)为顶点,网页内包含的超链接作为边,可 ...

  3. JVM:参数调优

    JVM:参数调优 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 前言 查看 JVM 系统默认值:使用 jps 和 jinfo 进行查看 -Xms:初始堆空间 - ...

  4. gson中TypeAdapter实现自定义序列化操作

    最近在项目中遇到这么一个问题,我们后台需要向前端返回一个 json 数据,就是将一个地理位置对象以json的格式返回到前台,但是这个地理位置对象中的经纬度是Double数据类型,项目中规定,如果经纬度 ...

  5. 攻防世界 杂项 3.神奇的Modbus

    [目标] 了解modbus协议 [工具] Wireshark [分析过程] 在数据包中寻找flag就行,flag是明文形式存储. 工业设备消息传输使用modbus协议.所以我就采集了modbus的通信 ...

  6. HBase的安装与部署

    一.部署前置环境 先部署分布式的高可用版的Hadoop,即ZooKeeper+Hadoop. https://www.cnblogs.com/live41/p/15483192.html * 部署的服 ...

  7. 转:Vivado IP报[Opt 31-67] 错误问题解决方法

    使用VIVADO编译代码时,其中一个IP报错,错误类似为 ImplementationOpt Design[Opt 31-67] Problem: A LUT2 cell in the design ...

  8. MVC之三个单选按钮的切换选择

    实现需求: 1.三个多选按钮中:只能同时选择限时抢购和分享金或者拼团特惠和分享金,其中限时抢购和拼团特惠不能同时选择.并且点击后显示,再次点击赢隐藏. 1 @*活动信息*@ 2 <div> ...

  9. 深入剖析Redis客户端Jedis的特性和原理

    一.开篇 Redis作为目前通用的缓存选型,因其高性能而倍受欢迎.Redis的2.x版本仅支持单机模式,从3.0版本开始引入集群模式. Redis的Java生态的客户端当中包含Jedis.Rediss ...

  10. 【数据结构&算法】08-栈概念&源码

    目录 前言 栈的定义 定义 常见应用 栈的常见应用 进栈出栈变化形式 栈的抽象数据类型 栈的顺序存储结构及实现 栈的顺序存储结构 顺序栈 顺序栈的结构定义 两栈共享空间 栈的链式存储结构及实现 栈的链 ...