luogu P4248 [AHOI2013]差异

链接

luogu

思路

\(\sum\limits_{1<=i<j<=n}{{len}(T_i)+{len}(T_j)-2*{lcp}(T_i,T_j)}\)

=\(\sum\limits_{1<=i<j<=n}{{len}(T_i)+{len}(T_j)}-\sum\limits_{1<=i<j<=n}2*{lcp}(T_i,T_j)\)

前半部分是\(\frac{n*(n+1)(n-1)}{2}\)

后半部分用sam求出parent tree的siz的过程中求解就行了。

两个串的lcp就是他们的lca的longest。

考虑子树内的贡献就行了。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+7;
int n,c[N<<1],a[N<<1];
char s[N];
struct sam {
int len,fa,ch[26];
}dian[N<<1];
int siz[N<<1],las=1,tot=1;
void add(int c,int k_th) {
int p=las;int np=las=++tot;
dian[np].len=dian[p].len+1;
for(;p&&!dian[p].ch[c];p=dian[p].fa) dian[p].ch[c]=np;
if(!p) dian[np].fa=1;
else {
int q=dian[p].ch[c];
if(dian[q].len==dian[p].len+1) dian[np].fa=q;
else {
int nq=++tot;
dian[nq]=dian[q];
dian[nq].len=dian[p].len+1;
dian[q].fa=dian[np].fa=nq;
for(;p&&dian[p].ch[c]==q;p=dian[p].fa)
dian[p].ch[c]=nq;
}
}
siz[las]=1;
}
signed main() {
scanf("%s",s+1);
n=strlen(s+1);
for(int i=n;i>=1;--i) add(s[i]-'a',i);
for(int i=1;i<=tot;++i) c[dian[i].len]++;
for(int i=1;i<=tot;++i) c[i]+=c[i-1];
for(int i=1;i<=tot;++i) a[c[dian[i].len]--]=i;
int ans=1LL*n*(n+1)*(n-1)/2;
for(int i=tot;i>=1;--i) {
ans-=2LL*siz[a[i]]*siz[dian[a[i]].fa]*dian[dian[a[i]].fa].len;
siz[dian[a[i]].fa]+=siz[a[i]];
}
printf("%lld",ans);
return 0;
}

luogu P4248 [AHOI2013]差异 SAM的更多相关文章

  1. Luogu P4248 [AHOI2013]差异

    题目链接 \(Click\) \(Here\) 神仙题.或者可能我太菜了没见过后缀数组的骚操作,然后就被秀了一脸\(hhhhh\) \[\sum\limits_{1<=i < j < ...

  2. P4248 [AHOI2013]差异 解题报告

    P4248 [AHOI2013]差异 题目描述 给定一个长度为 \(n\) 的字符串 \(S\),令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀.求 \[\displaystyle \s ...

  3. P4248 [AHOI2013]差异

    思路 SAM 后缀自动机parent树的LCA就是两个子串的最长公共后缀 现在要求LCP 所以把字符串反转一下 然后每个点的贡献就是endpos的大小,dfs一遍求出贡献就可以了 代码 #includ ...

  4. 洛谷P4248 [AHOI2013]差异(后缀自动机求lcp之和)

    题目见此 题解:首先所有后缀都在最后一个np节点,然后他们都是从1号点出发沿一些字符边到达这个点的,所以下文称1号点为根节点,我们思考一下什么时候会产生lcp,显然是当他们从根节点开始一直跳相同节点的 ...

  5. BZOJ3238:[AHOI2013]差异(SAM)

    Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N< ...

  6. [洛谷P4248][AHOI2013]差异

    题目大意:给一个长度为$n$的字符串,求: $$\sum\limits_{1\leqslant i<j\leqslant n}|suf_i|+|suf_j|-2\times lcp(suf_i, ...

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

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

  8. BZOJ3238 [Ahoi2013]差异 【SAM or SA】

    BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单 ...

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

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

随机推荐

  1. 【1】【leetcode-17】电话号码的字母组合

    给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 1 不对应任何字母. 示例: 输入:"23"输出:[" ...

  2. C# - List.Sort()自定义排序方法

    本文通过示例介绍了C#中典型容器List.Sort()的自定义排序方法,进而引出了C#中自定义排序的核心接口及方法 项目地址:自定义Sort方法 - SouthBegonia's Github Lis ...

  3. wps金山文档在线编辑--.Net 接入指南

    一.申请成为服务商,对金山文档在线服务进行申请 ①进入官网 https://open.wps.cn/ ②申请后如下图,点击右下角的进入服务 ③申请成功后 ④数据回调URL一定是服务器地址,本次我使用的 ...

  4. 用python完成排序算法

    排序算法总结 冒泡排序 相邻两个元素,两两循环比较,每趟筛选出一个最大或者最小的元素(有序区在后面) def bubble_sort(data): # 第一层循环:循环一次,代表一趟,并筛选出一个最大 ...

  5. 并发编程--一堆锁,GIL,同步异步,Event事件

    目录 一堆锁 死锁现象(*****) 递归锁 RLock (了解) 信号量 (了解) GIL(*****) 什么时GIL锁 为什么需要GIL锁 Cpython解释器与GC的问题 GIL锁带来的问题 多 ...

  6. java中创建线程的3种方法

    1.继承Thread类优点:可以直接使用Thread类中的方法,代码比较简单.缺点:继承Thread类之后不能继承其他类. 2.实现Runable接口优点:实现接口,比影响继承其他类或实现接口.缺点: ...

  7. 关于js保留两位小数方法总结

    https://www.cnblogs.com/le220/p/9756881.htmlhttps://blog.csdn.net/hyb1234hi/article/details/84142721 ...

  8. SQLi_Labs通关文档【1-65关】

    SQLi_Labs通关文档[1-65关] 为了不干扰自己本机环境,SQL-LAB我就用的码头工人,跑起来的,搭建也非常简单,也就两条命令 docker pull acgpiano/sqli-labs ...

  9. 医疗行业预测性产品的质量如何把关?MES系统帮大忙

    作为行业细分的医疗设备制造正在向工业4.0快速发展.它也可能仍然是世界上受监管最严格的行业之一,产品的个性化发展速度比其他行业更快. 在医疗设备行业中,由于需求或由于市场特定的规定,产品越来越多地定制 ...

  10. Protobuf协议应用干货

    Protobuf应用广泛,尤其作为网络通讯协议最为普遍.本文将详细描述几个让人眼前一亮的protobuf协议设计,对准备应用或已经应用protobuf的开发者会有所启发,甚至可以直接拿过去用. 这里描 ...