luogu P4248 [AHOI2013]差异 SAM
luogu P4248 [AHOI2013]差异
链接
思路
\(\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的更多相关文章
- Luogu P4248 [AHOI2013]差异
题目链接 \(Click\) \(Here\) 神仙题.或者可能我太菜了没见过后缀数组的骚操作,然后就被秀了一脸\(hhhhh\) \[\sum\limits_{1<=i < j < ...
- P4248 [AHOI2013]差异 解题报告
P4248 [AHOI2013]差异 题目描述 给定一个长度为 \(n\) 的字符串 \(S\),令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀.求 \[\displaystyle \s ...
- P4248 [AHOI2013]差异
思路 SAM 后缀自动机parent树的LCA就是两个子串的最长公共后缀 现在要求LCP 所以把字符串反转一下 然后每个点的贡献就是endpos的大小,dfs一遍求出贡献就可以了 代码 #includ ...
- 洛谷P4248 [AHOI2013]差异(后缀自动机求lcp之和)
题目见此 题解:首先所有后缀都在最后一个np节点,然后他们都是从1号点出发沿一些字符边到达这个点的,所以下文称1号点为根节点,我们思考一下什么时候会产生lcp,显然是当他们从根节点开始一直跳相同节点的 ...
- BZOJ3238:[AHOI2013]差异(SAM)
Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N< ...
- [洛谷P4248][AHOI2013]差异
题目大意:给一个长度为$n$的字符串,求: $$\sum\limits_{1\leqslant i<j\leqslant n}|suf_i|+|suf_j|-2\times lcp(suf_i, ...
- 【BZOJ 3238】 3238: [Ahoi2013]差异(SAM)
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3047 Solved: 1375 Description In ...
- BZOJ3238 [Ahoi2013]差异 【SAM or SA】
BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单 ...
- BZOJ 3238: [Ahoi2013]差异 [后缀自动机]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2512 Solved: 1140[Submit][Status ...
随机推荐
- SQL语句--删除掉重复项只保留一条
用SQL语句,删除掉重复项只保留一条 在几千条记录里,存在着些相同的记录,如何能用SQL语句,删除掉重复的呢1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select ...
- Ubuntu安装MySQL配置远程登录、utf8mb4字符集
2019/11/19, Ubuntu Server 18.04,MySQL 5.7 摘要:Ubuntu Server 18.04 安装MySQL 5.7 并配置远程登录.utf8mb4字符集 由于My ...
- Smack Extensions用户手册
Smack Extensions用户手册 XMPP协议包括基本协议和许多可选扩展,通常记录为“XEP”.Smack为核心XMPP协议提供了org.jivesoftware.smack包,为许多协议扩展 ...
- ubuntu ufw相关命令
引自:http://www.cnblogs.com/jiangyao/archive/2010/05/19/1738909.html 就这句话就够了,下面的可以不看 sudo ufw enable| ...
- python爬虫之Scrapy学习
在爬虫的路上,学习scrapy是一个必不可少的环节.也许有好多朋友此时此刻也正在接触并学习scrapy,那么很好,我们一起学习.开始接触scrapy的朋友可能会有些疑惑,毕竟是一个框架,上来不知从何学 ...
- webpack 入门和常用插件的使用
常用配置参数 module.exports = { context: path.resolve(__dirname, '../'), entry: { app: './src/main.js' }, ...
- Protobuf协议应用干货
Protobuf应用广泛,尤其作为网络通讯协议最为普遍.本文将详细描述几个让人眼前一亮的protobuf协议设计,对准备应用或已经应用protobuf的开发者会有所启发,甚至可以直接拿过去用. 这里描 ...
- Linux装B命令
原文:https://mp.weixin.qq.com/s/CNmMRjl0iZ8EBPq5VgJHsA 1.空心字体 yum install -y figlet figlet happy 1.0 2 ...
- SVM 实现多分类思路
svm 是针对二分类问题, 如果要进行多分类, 无非就是多训练几个svm呗 OVR (one versus rest) 对于k个类别(k>2) 的情况, 训练k个svm, 其中, 第j个svm用 ...
- 服务器安装python3环境
服务器安装python3环境 先安装相关包 yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel re ...