题意

给定字符串,令$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的更多相关文章

  1. BZOJ 3238: [Ahoi2013]差异 后缀自动机 树形dp

    http://www.lydsy.com/JudgeOnline/problem.php?id=3238 就算是全局变量,也不要忘记,初始化(吐血). 长得一副lca样,没想到是个树形dp(小丫头还有 ...

  2. BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)

    题目链接 \(Description\) \(Solution\) len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次. \[\sum_{i=1}^n\sum_{j=i+1 ...

  3. BZOJ.4199.[NOI2015]品酒大会(后缀自动机 树形DP)

    BZOJ 洛谷 后缀数组做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 只考虑求极长相同子串,即所有后缀之间的LCP. 而后缀的LCP在后缀树的LCA处.同差异这道题,在每个点处 ...

  4. BZOJ 3238 差异

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

  5. [BZOJ 4033] [HAOI2015] T1 【树形DP】

    题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...

  6. [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩)

    [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩) 题面 给出一棵树和一个图,点数均为n,问有多少种方法把树的节点标号,使得对于树上的任意两个节点u,v,若树上u ...

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

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

  8. BZOJ 3238 [Ahoi2013]差异 ——后缀自动机

    后缀自动机的parent树就是反串的后缀树. 所以只需要反向构建出后缀树,就可以乱搞了. #include <cstdio> #include <cstring> #inclu ...

  9. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

随机推荐

  1. Coursera machine learning 第二周 quiz 答案 Linear Regression with Multiple Variables

    https://www.coursera.org/learn/machine-learning/exam/7pytE/linear-regression-with-multiple-variables ...

  2. java基础之【堆、栈、方法区】结构图

    |--数组实例化过程 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHViaWFvXzA2MTg=/font/5a6L5L2T/fontsize/400/ ...

  3. LCD驱动程序(二)

    上节我们主要是对fb_info结构体的配置,对fb_info结构体的配置主要分为一下步骤: static int lcd_init(void){ /* 1. 分配一个fb_info */ s3c_lc ...

  4. sqlserver删除所有表

    --/第1步**********删除所有表的外键约束*************************/ DECLARE c1 cursor for select 'alter table ['+ o ...

  5. word2vec_basic.py

    ssh://sci@192.168.67.128:22/usr/bin/python3 -u /home/win_pymine_clean/feature_wifi/word2vec_basic.py ...

  6. make编译一

    在C和C++中,首先要把源文件编译成中间代码文件,在windows下就是obj文件,linux下就是.o文件:object file.这个动作叫做编译,然后再把大量的object file合成执行文件 ...

  7. 基本操作——word中怎样同一页中放入多张图片

    可能很多人在放图片时候,碰见这种情况,习惯性的把图片拖进word,发现不能在一页上很工整的排列.很多人包括我刚开始也纳闷,怎么不能一页中放入几张图片呢,缩放也不想.下面分享一个小技巧给有缘人 以我的w ...

  8. 蓝屏代码stop:0X000000EA(0X85E286B8,0X8635F210,0XF7A53CBC,0X00000001)

    你这是显卡驱动问题,我把蓝屏代码都给你,以后在出现蓝屏自己看看行了. 1.0x0000000A:IRQL_NOT_LESS_OR_EQUAL ◆错误分析:主要是由问题的驱动程序.有缺陷或不兼容的硬件与 ...

  9. Oracle数据库体系结构(7) 表空间管理1

    表空间是Oracle数据库最大的逻辑存储结构,有一系列段构成.Oracle数据库对象存储结构的管理主要是通过表空间的管理实现的. 1.表空间的分类 表空间根据存储类型不同分为系统表空间和非系统表空间 ...

  10. 两个小例子彻底明白python decorator

    一:没有什么实际意思,就是单纯的理解decorator.使用装饰器完全可以阻止方法中的代码执行. class json_test(object): def __init__(self, *arg, * ...