【BZOJ 3238】差异 后缀自动机+树形DP
题意
给定字符串,令$s_i$表示第$i$位开始的后缀,求$\sum_{1\le i < j \le n} len(s_i)+len(s_j)-2\times lcp(s_i,s_j)$
先考虑前面的和式,直接计算为$\frac{n(n^2-1)}{2}$,考虑后面的和式,$lcp$相关可以用sam求解,sam形成的parent树是原串的前缀树,所以两个串的最长公共后缀是在parent树上最近公共祖先对应的状态的长度$maxlen_s-maxlen_{pa_s}$,将原串反向建立sam得到后缀树,parent树上每个状态的子串个数为$Right_s$,每个状态的贡献为$2\times \binom{Right_s}{2}\times (maxlen_s-maxlen_{pa_s})$,在parent树上跑一遍dp即可求出
时间复杂度$O(n)$
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1001000;
int trans[N][30], pa[N], maxlen[N], sz, root, last, Right[N];
inline void init_sam() {
memset(trans, 0, sizeof(trans));
root = last = sz = 1;
}
inline void extend(int c, int x) {
int p = last, np = ++sz; last = np; maxlen[np] = x; Right[np] = 1;
for(; p && !trans[p][c]; p = pa[p]) trans[p][c] = np;
if(!p) {pa[np] = root; return;}
int q = trans[p][c];
if(maxlen[q] == maxlen[p] + 1) {
pa[np] = q;
}else {
int nq = ++sz;
memcpy(trans[nq], trans[q], sizeof(trans[q]));
pa[nq] = pa[q]; maxlen[nq] = maxlen[p] + 1; pa[q] = pa[np] = nq;
for(; trans[p][c] == q; p = pa[p]) trans[p][c] = nq;
}
}
inline void build(char *s) {
int len = strlen(s);
for(int i = 0; i < len; ++i) extend(s[i] - 'a', i + 1);
}
int cnt, head[N], nxt[N], to[N];
inline void init_edge() {cnt = 0; memset(head, -1, sizeof(head));}
inline void add(int u, int v) {to[cnt] = v; nxt[cnt] = head[u]; head[u] = cnt++;}
LL ans = 0;
int dfs(int u) {
for(int i = head[u]; ~i; i = nxt[i]) Right[u] += dfs(to[i]);
ans -= 1LL * Right[u] * (Right[u] - 1) * (maxlen[u] - maxlen[pa[u]]);
return Right[u];
}
inline void get() {
init_edge();
for(int i = 2; i <= sz; ++i) add(pa[i], i);
dfs(root);
}
char str[N];
int main() {
scanf("%s", str);
int len = strlen(str);
reverse(str, str + len);
init_sam();
build(str);
ans = 1LL * len * (len - 1) * (len + 1) / 2;
get();
cout << ans << endl;
return 0;
}
【BZOJ 3238】差异 后缀自动机+树形DP的更多相关文章
- BZOJ 3238: [Ahoi2013]差异 后缀自动机 树形dp
http://www.lydsy.com/JudgeOnline/problem.php?id=3238 就算是全局变量,也不要忘记,初始化(吐血). 长得一副lca样,没想到是个树形dp(小丫头还有 ...
- BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)
题目链接 \(Description\) \(Solution\) len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次. \[\sum_{i=1}^n\sum_{j=i+1 ...
- BZOJ.4199.[NOI2015]品酒大会(后缀自动机 树形DP)
BZOJ 洛谷 后缀数组做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 只考虑求极长相同子串,即所有后缀之间的LCP. 而后缀的LCP在后缀树的LCA处.同差异这道题,在每个点处 ...
- BZOJ 3238 差异
BZOJ 3238 差异 看这个式子其实就是求任意两个后缀的 $ LCP $ 长度和.前面的 $ len(T_i)+len(T_j) $ 求和其实就是 $ n(n-1)(n+1)/2 $ ,这个是很好 ...
- [BZOJ 4033] [HAOI2015] T1 【树形DP】
题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...
- [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩)
[BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩) 题面 给出一棵树和一个图,点数均为n,问有多少种方法把树的节点标号,使得对于树上的任意两个节点u,v,若树上u ...
- BZOJ 3238: [Ahoi2013]差异 [后缀自动机]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2512 Solved: 1140[Submit][Status ...
- BZOJ 3238 [Ahoi2013]差异 ——后缀自动机
后缀自动机的parent树就是反串的后缀树. 所以只需要反向构建出后缀树,就可以乱搞了. #include <cstdio> #include <cstring> #inclu ...
- BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...
随机推荐
- QT应用程序 安装路径中文异常问题
[1]QT 安装中文路径启动异常问题 最近在搞一个很简单的QT应用程序,开发环境VS2017 + QT5.9,线上异常报错:安装中文路径下启动崩溃~~~~ 最后,本地调试Debug版本,发现安装中文路 ...
- 从头认识java-17.5 堵塞队列(以生产者消费者模式为例)
这一章节我们来讨论一下堵塞队列.我们以下将通过生产者消费者模式来介绍堵塞队列. 1.什么是堵塞队列?(摘自于并发编程网对http://tutorials.jenkov.com/java-concurr ...
- Linux下tar解压缩命令
1.打包命令: 命令格式:tar -zcvf 压缩文件名.tar.gz 被压缩文件名 可先切换到当前目录下.压缩文件名和被压缩文件名都可加入路径. 2.解包命令: 命令格式:tar -zx ...
- python入门课程 第3章 Python变量和数据类型
第3章 Python变量和数据类型3-1 Python中数据类型计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形 ...
- POJ 1860
须要推断是否有正权环存在,Bellman-Ford算法就能够辣~ AC代码: #include <iostream> #include <cstdio> #include &l ...
- 初步认识Spring MVC框架
Spring MVC 框架和Struts2等一样属于MVC框架,用于处理页面和后台的交互,据说它的效率要高于Struts2.下面县先说一下Spring MVC的结构,Spring MVC主要由Disp ...
- Robbery(记忆化搜索)
Robbery Inspector Robstop is very angry. Last night, a bank has been robbed and the robber has not b ...
- HTML元素嵌套关系
- intellij idea 自动生成setter getter
windows下: alt + insert,然后选择要生成的成员. mac下: command + N
- iOS9 3D Touch使用
http://www.cnblogs.com/zhanglinfeng/p/5133939.html