bzoj 3238: [Ahoi2013]差异 后缀树
来源:互联网 发布:淘宝店铺永久冻结 编辑:程序博客网 时间:2024/04/29 18:41
学习了一下后缀自动机转后缀树的方法。虽然可能这道题目后缀数组也可以做。
考虑后缀自动机的parent,它对应的是比x的right集合略大一点的那个节点;对应到后缀树上,可以发现在缩边后对应的就是y的父亲。
但是后缀自动机求得实际上是所有前缀倒过来后的后缀树;因此把原串反过来跑sam,然后x连向fa[x]就是后缀树了;每个点的len实际上就是这个节点的深度。
然后考虑这道题目,本质就是求两两的lcp的长度,那就对每个后缀树上的节点求一下就好了。
AC代码如下:
#include<bits/stdc++.h>#define ll long long#define N 1000005using namespace std;int n; char s[N];struct sam{int cnt,last,ch[N][26],len[N],fa[N],fst[N],nxt[N],sz[N];ll ans;sam(){ cnt=last=1; }void ins(int c){int p=last,np=last=++cnt; len[np]=len[p]+1; sz[cnt]=1;for (; p && !ch[p][c]; p=fa[p]) ch[p][c]=np;if (!p) fa[np]=1; else{int q=ch[p][c];if (len[p]+1==len[q]) fa[np]=q; else{int nq=++cnt; len[nq]=len[p]+1;memcpy(ch[nq],ch[q],sizeof(ch[q]));fa[nq]=fa[q]; fa[np]=fa[q]=nq;for (; p && ch[p][c]==q; p=fa[p]) ch[p][c]=nq;}}}void dfs(int x){int y;for (y=fst[x]; y; y=nxt[y]){dfs(y);ans+=(ll)len[x]*sz[x]*sz[y]; sz[x]+=sz[y];}}void solve(){int i;for (i=2; i<=cnt; i++){nxt[i]=fst[fa[i]]; fst[fa[i]]=i;}dfs(1);printf("%lld\n",((ll)n*(n-1)*(n+1)>>1)-(ans<<1));}}sam;int main(){scanf("%s",s+1); n=strlen(s+1);int i;for (i=n; i; i--) sam.ins(s[i]-'a');sam.solve();return 0;}
by lych
2017.3.16
0 0
- bzoj 3238: [Ahoi2013]差异 后缀树
- 【BZOJ 3238】[Ahoi2013]差异 后缀自动机构造后缀树
- BZOJ 3238 AHOI2013 差异 后缀自动机
- bzoj 3238: [Ahoi2013]差异 后缀数组
- BZOJ 3238: [Ahoi2013]差异 后缀数组
- bzoj 3238: [Ahoi2013]差异 后缀自动机
- bzoj 3238 ahoi2013差异 后缀数组
- BZOJ 3238 [Ahoi2013]差异 后缀自动机
- 【BZOJ 3238】 [Ahoi2013]差异
- bzoj 3238: [Ahoi2013]差异
- BZOJ 3238 [Ahoi2013]差异
- bzoj 3238 [Ahoi2013]差异
- [后缀自动机 构建后缀树 树形DP] BZOJ 3238 [Ahoi2013]差异
- BZOJ 3238 [Ahoi2013]差异 后缀数组+单调栈
- BZOJ 3238: [Ahoi2013]差异|后缀数组|乘法原理
- bzoj 3238 [Ahoi2013]差异 后缀数组 并查集
- bzoj 3238: [Ahoi2013]差异 (后缀自动机+树形dp)
- BZOJ 3238 [Ahoi2013]差异 后缀数组+st表
- lintcode(115)不同的路径2
- Apache+PHP+MySql -- 常用配置地址
- 【技能库】--完整的RPC框架示例(143)
- 矩阵n*m找出最大值的行列号及值
- Linux常用配置命令
- bzoj 3238: [Ahoi2013]差异 后缀树
- MFC Windows程序设计学习笔记--菜单
- BZOJ 2989 数列
- Android开发之深入理解Android 6.0、7.0系统权限
- m阶方针对角线所有元素的和
- 矩阵的和
- 一只大二狗的Android历程--PNG图片的Crunching Cruncher错误解决办法
- Java并发编程:volatile关键字解析
- 矩阵相乘