题目链接

\[ans=\sum_{1<=i<j<=n}len(T_i)+len(T_j)-2*lcp(T_i,T_j)
\]

观察这个式子可以发现,前面两个\(len\)是常数,后面的其实就是反串有每对前缀的相同后缀乘以其长度之和。

两个前缀的相同后缀就是这两个串在parent tree上对应的点的\(LCA\),于是直接树上统计就行了。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1000010;
struct SAM{
int ch[26];
int len, fa;
}sam[MAXN << 1];
int las = 1, cnt = 1, f[MAXN << 1];
struct Edge{
int next, to;
}e[MAXN << 1];
int head[MAXN << 1], num, n;
inline void Add(int from, int to){
e[++num].to = to; e[num].next = head[from]; head[from] = num;
}
inline void add(int c){
int p = las; int np = las = ++cnt;
sam[np].len = sam[p].len + 1; f[cnt] = 1;
for(; p && !sam[p].ch[c]; p = sam[p].fa) sam[p].ch[c] = np;
if(!p) sam[np].fa = 1;
else{
int q = sam[p].ch[c];
if(sam[q].len == sam[p].len + 1) sam[np].fa = q;
else{
int nq = ++cnt; sam[nq] = sam[q];
sam[nq].len = sam[p].len + 1;
sam[q].fa = sam[np].fa = nq;
for(; p && sam[p].ch[c] == q; p = sam[p].fa) sam[p].ch[c] = nq;
}
}
}
char a[MAXN];
long long ans;
void dfs(int u){
long long tmp = 0;
for(int i = head[u]; i; i = e[i].next){
dfs(e[i].to);
tmp += (long long)f[u] * f[e[i].to];
f[u] += f[e[i].to];
}
ans += (long long)tmp * 2 * sam[u].len;
}
int main(){
scanf("%s", a + 1);
n = strlen(a + 1);
for(int i = 1; i <= n; ++i)
add(a[i] - 'a');
for(int i = 2; i <= cnt; ++i)
Add(sam[i].fa, i);
dfs(1);
printf("%lld\n", (long long)n * (n - 1) * (n + 1) / 2 - ans);
return 0;
}

【洛谷 P4248】 [AHOI2013]差异(后缀自动机)的更多相关文章

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

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

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

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

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

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

  4. [Ahoi2013]差异(后缀自动机)

    /* 前面的那一坨是可以O1计算的 后面那个显然后缀数组单调栈比较好写??? 两个后缀的lcp长度相当于他们在后缀树上的lca的深度 那么我们就能够反向用后缀自动机构造出后缀树然后统计每个点作为lca ...

  5. [bzoj3238][Ahoi2013]差异——后缀自动机

    Brief Description Algorithm Design 下面给出后缀自动机的一个性质: 两个子串的最长公共后缀,位于这两个串对应的状态在parent树上的lca状态上.并且最长公共后缀的 ...

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

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

  7. [AHOI2013]差异 后缀自动机_Parent树

    题中要求: $\sum_{1\leqslant i < j \leq n } Len(T_{i}) +Len(T_{j})-2LCP(T_{i},T_{j})$ 公式左边的部分很好求,是一个常量 ...

  8. 洛谷4248 AHOI2013差异 (后缀数组SA+单调栈)

    补博客! 首先我们观察题目中给的那个求\(ans\)的方法,其实前两项没什么用处,直接\(for\)一遍就求得了 for (int i=1;i<=n;i++) ans=ans+i*(n-1); ...

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

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

  10. BZOJ3238: [Ahoi2013]差异(后缀自动机)

    题意 题目链接 Sol 前面的可以直接算 然后原串翻转过来,这时候变成了求任意两个前缀的最长公共后缀,显然这个值应该是\(len[lca]\),求出\(siz\)乱搞一下 #include<bi ...

随机推荐

  1. 记录linux上mongo迁移使用的命令

    首先mongodb的文件路径必须在系统盘,这里是 这里安装路径 /usr/mongodb/bin 一般迁移的只是db文件夹和log文件 看配置文件内容 port=27017 #端口 dbpath=/d ...

  2. 各种系统性能优化技术,采用vilocity实现商品页面静态化

    1.大型门户网站系统:>10万的访问量   行业网站(当当网,卓越网):20万-30万,一个小时内会跟数据库的交互至少20万-30万,会产生数据库瓶颈,每个数据库都有一个最大连接数(socket ...

  3. [C++] new和delete运算符使用方法

    new 和 delete 是C++语言中的两个运算符,配套使用. new:用于分配内存,与C语言中的 malloc 相同,分配在堆内存 delete:用于释放内存,与C语言中的 free 相同,释放堆 ...

  4. ActionFilter、IAuthorizationFilter 权限验证重定向跳转到其它页面

    方法一: public class IsAllowAttribute: ActionFilterAttribute { public override void OnActionExecuting(A ...

  5. PostgreSQL--with子句

    在PostgreSQL中,WITH查询提供了一种编写辅助语句的方法,以便在更大的查询中使用.它有助于将复杂的大型查询分解为更简单的表单,便于阅读.这些语句通常称为公共表表达式(Common Table ...

  6. flex布局大全

    有句话叫做:存在即是合理. 最近很喜欢flex布局模式,不过还在摸索中,这里正一边在项目中使用和总结,也在学习一些大牛们总结的东西和布局思考. 鉴于自己很苦恼,到处去ha资料,真的,就没有一个系统的, ...

  7. GoLand 2019.1 激活破解

    链接://https://blog.csdn.net/hi_liuxiansheng/article/details/89078405

  8. ou can mix require and export. You can't mix import and module.exports.

    ou can mix require and export. You can't mix import and module.exports.

  9. C# 编译器 和 反编译器,你要哪个(歪头)? 我全都要(捏拳)!

    前言 从 C# 6.0 开始,C# 编译器就从以前由 C++ 实现的 csc.exe 换成了用 C# 重新实现的开放式 API 式编译服务 Roslyn.这个编译器到现在已经替代了老式编译器,从前 W ...

  10. layui父页面获取子页面数据

    var doc = layero.find('iframe')[0].contentDocument; var test= $(doc).find("input[name='test']&q ...