题目传送门:洛谷 P4248

题意简述:

定义两个字符串 \(S\) 和 \(T\) 的差异 \(\operatorname{diff}(S,T)\) 为这两个串的长度之和减去两倍的这两个串的最长公共前缀的长度。

给定一个字符串,定义从第 \(i\) 个字符开始的后缀为 \(Suf_i\)。

求 \(\sum_{1\le i<j\le n}\operatorname{diff}(Suf_i,Suf_j)\)。

题解:

化简式子,原式等于

\[\begin{align*}&\left(\sum_{1\le i<j\le n}i+j\right)-2\times\sum_{1\le i<j\le n}\operatorname{lcp}(Suf_i,Suf_j)\\=& \frac{n(n-1)(n+1)}{2}-2\times\sum_{1\le i<j\le n}\operatorname{lcp}(Suf_i,Suf_j)\end{align*}\]

所以只要求出后半部分即可。

建立字符串的后缀数组。

考虑 Height 数组的贡献:Height 数组中 [2, n] 内的每一个区间都给答案贡献区间最小值。

套路:每个区间的区间最小值之和,使用单调栈解决。

 #include <cstdio>
#include <cstring> typedef long long LL;
const int MN = ; int N;
char str[MN]; int M;
int rk[MN], rk2[MN], SA[MN], SA2[MN];
int buk[MN], cnt;
int Height[MN]; void GetHeight() {
int k = ;
for (int i = ; i <= N; ++i) {
if (rk[i] == ) { k = Height[] = ; continue; }
if (k) --k;
int j = SA[rk[i] - ];
while (i + k <= N && j + k <= N && str[i + k] == str[j + k]) ++k;
Height[rk[i]] = k;
}
} void Rsort() {
for (int i = ; i <= M; ++i) buk[i] = ;
for (int i = ; i <= N; ++i) ++buk[rk[i]];
for (int i = ; i <= M; ++i) buk[i] += buk[i - ];
for (int i = N; i >= ; --i) SA[buk[rk[SA2[i]]]--] = SA2[i];
} void GetSA() {
M = ;
for (int i = ; i <= N; ++i) rk[i] = str[i] - 'a' + , SA2[i] = i;
Rsort();
for (int j = ; j < N; j <<= ) {
int P = ;
for (int i = N - j + ; i <= N; ++i) SA2[++P] = i;
for (int i = ; i <= N; ++i) if (SA[i] > j) SA2[++P] = SA[i] - j;
Rsort();
rk2[SA[]] = P = ;
for (int i = ; i <= N; ++i) {
if (rk[SA[i]] != rk[SA[i - ]] || rk[SA[i] + j] != rk[SA[i - ] + j]) ++P;
rk2[SA[i]] = P;
}
for (int i = ; i <= N; ++i) rk[i] = rk2[i];
M = P;
if (M == N) break;
}
GetHeight();
} int st[MN], t;
int L[MN], R[MN]; int main() {
scanf("%s", str + );
N = strlen(str + );
GetSA();
st[t = ] = ;
for (int i = ; i <= N; ++i) {
while (t && Height[st[t]] > Height[i]) R[st[t--]] = i;
L[i] = st[t];
st[++t] = i;
} while (t) R[st[t--]] = N + ;
LL Ans = (LL)(N - ) * N * (N + ) / ;
for (int i = ; i <= N; ++i)
Ans -= 2ll * (R[i] - i) * (i - L[i]) * Height[i];
printf("%lld\n", Ans);
return ;
}

洛谷 P4248: bzoj 3238: [AHOI2013]差异的更多相关文章

  1. 洛谷 P4248 / loj 2377 [AHOI2013] 差异 题解【后缀自动机】【树形DP】

    可能是一个 SAM 常用技巧?感觉 SAM 的基础题好多啊.. 题目描述 给定一个长度为 \(n\) 的字符串 \(S\) ,令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀,求: \[ ...

  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: [Ahoi2013]差异 -- 后缀数组

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

  6. ●BZOJ 3238 [Ahoi2013]差异

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

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

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

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

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

  9. BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))

    [传送门[(https://www.lydsy.com/JudgeOnline/problem.php?id=3238) 解题思路 首先原式可以把\(len\)那部分直接算出来,然后通过后缀数组求\( ...

随机推荐

  1. Acdream1311_Apple

    无聊的时候看到上一次acdream群赛的一个题目,中间居然是有alice和bob的博弈题目,于是就去做了. 给n,m,两人轮流操作,每次操作可以使n+1,或者m+1,谁操作后满足nm>=A,那么 ...

  2. SourceTree轻松Git项目

    这篇文档的目的是:让使用Git更轻松. 看完这篇文档你能做到的是: 1.简单的用Git管理项目. 2.怎样既要开发又要处理发布出去的版本bug情况. SourceTree是一个免费的Git图形化管理工 ...

  3. Theme Section HDU - 4763(些许暴力)

    题意: 求出最长公共前后缀 不能重叠  而且 这个前后缀 在串的中间也要出现一次 解析: 再明确一次next数组的意思:完全匹配的最长前后缀长度 求一遍next 然后暴力枚举就好了 #include ...

  4. MT【157】至少一个小于1

    若函数$f(x)=x^2+ax+b$有两个不等实数根$x_1,x_2$,且$1<x_1<x_2<3$,那么$f(1),f(3)中$    (      )A.只有一个小于1 B.至少 ...

  5. 51nod 1471 小S的兴趣 | 分块 链表

    51nod 1471 小S的兴趣 题面 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题 ...

  6. 20135319zl字符集报告

    字符集实验 ASCII 首先,查找ZHULI五个字符对应的ASCII码,5a 48 55 4c 49. 然后,用vim打开一个空文档,按下":",输入%!xxd 然后,输入 000 ...

  7. bzoj 2428: [HAOI2006]均分数据 && bzoj 3680 : 吊打XXX 模拟退火

    每次把元素随便扔随机一个初始解,退火时每次随机拿一个元素扔到随机一个集合里,当温度高时因为状态不稳定扔到那个元素和最小的里边. 如果新解优,更新ans. 把原式拆一下,就可以用int存了. bzoj ...

  8. Python word_cloud 样例 标签云系列(三)

    转载地址:https://zhuanlan.zhihu.com/p/20436642word_cloud/examples at master · amueller/word_cloud · GitH ...

  9. increment/decrement/dereference

    #include <vector> #include <deque> #include <algorithm> #include <iostream> ...

  10. NAT ------ 为什么手动设置NAT端口映射(转发)不成功,导致访问不了局域网服务器

    手动设置端口映射成功的条件是路由器WAN口接的是外网IP,而不是网络提供商的路由器NAT之后的IP.假如有个外网的客户端,连的服务器IP一定要是外网IP(假设IP_A),如果自己的路由器WAN口接的是 ...