【洛谷 P4248】 [AHOI2013]差异(后缀自动机)
\]
观察这个式子可以发现,前面两个\(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]差异(后缀自动机)的更多相关文章
- 洛谷P4248 [AHOI2013]差异(后缀自动机求lcp之和)
题目见此 题解:首先所有后缀都在最后一个np节点,然后他们都是从1号点出发沿一些字符边到达这个点的,所以下文称1号点为根节点,我们思考一下什么时候会产生lcp,显然是当他们从根节点开始一直跳相同节点的 ...
- [洛谷P4248][AHOI2013]差异
题目大意:给一个长度为$n$的字符串,求: $$\sum\limits_{1\leqslant i<j\leqslant n}|suf_i|+|suf_j|-2\times lcp(suf_i, ...
- BZOJ 3238: [Ahoi2013]差异 [后缀自动机]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2512 Solved: 1140[Submit][Status ...
- [Ahoi2013]差异(后缀自动机)
/* 前面的那一坨是可以O1计算的 后面那个显然后缀数组单调栈比较好写??? 两个后缀的lcp长度相当于他们在后缀树上的lca的深度 那么我们就能够反向用后缀自动机构造出后缀树然后统计每个点作为lca ...
- [bzoj3238][Ahoi2013]差异——后缀自动机
Brief Description Algorithm Design 下面给出后缀自动机的一个性质: 两个子串的最长公共后缀,位于这两个串对应的状态在parent树上的lca状态上.并且最长公共后缀的 ...
- BZOJ 3238 [Ahoi2013]差异 ——后缀自动机
后缀自动机的parent树就是反串的后缀树. 所以只需要反向构建出后缀树,就可以乱搞了. #include <cstdio> #include <cstring> #inclu ...
- [AHOI2013]差异 后缀自动机_Parent树
题中要求: $\sum_{1\leqslant i < j \leq n } Len(T_{i}) +Len(T_{j})-2LCP(T_{i},T_{j})$ 公式左边的部分很好求,是一个常量 ...
- 洛谷4248 AHOI2013差异 (后缀数组SA+单调栈)
补博客! 首先我们观察题目中给的那个求\(ans\)的方法,其实前两项没什么用处,直接\(for\)一遍就求得了 for (int i=1;i<=n;i++) ans=ans+i*(n-1); ...
- BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)
题目链接 \(Description\) \(Solution\) len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次. \[\sum_{i=1}^n\sum_{j=i+1 ...
- BZOJ3238: [Ahoi2013]差异(后缀自动机)
题意 题目链接 Sol 前面的可以直接算 然后原串翻转过来,这时候变成了求任意两个前缀的最长公共后缀,显然这个值应该是\(len[lca]\),求出\(siz\)乱搞一下 #include<bi ...
随机推荐
- pycharm plot独立窗口显示
import matplotlib.pyplot as plt ... plt.show() 进行如下设置: File->Settings->Tools->Python Scient ...
- max函数比较字符串类型
关于sql中 max函数比较字符串类型 max只比较首个字符的大小 只要首字母大,则不比较其他位置的字母,若首字母相同,则比较顺序位字母. 今天死在这了 数据库中 step字段类型char分别为 5. ...
- redis-sentinel 高可用方案实践
近期公司的一块核心业务使用redis作为配置转发中心,存在单点问题,考虑服务的可靠性.针对业务需求,我们确定了我们的需求: 异地跨机房容灾 故障自动切换 尽可能高的保证数据不丢失 针对以上需求,我们分 ...
- 子查询优化 - Hyper
Unnesting Arbitrary Queries - T Neumann, A KemperThe Complete Story of Joins (in HyPer) - Thomas Neu ...
- Python执行时间的计算方法
# CPU的执行时间start = time.clock()#end = time.clock()print(end-start) # 程序执行时间:start = datetime.datetime ...
- 微信小程序开发——文本框种输入手机号,点击获取验证码无反应的处理方法
异常描述: 如下图,输入手机号码之后,点击右侧的获取验证码,在开发工具是OK的,真机测试无反应: 页面编码跟H5差不多的,H5没出现这个问题,但是小程序就不一样了. 异常分析: 页面结构层面,为了方便 ...
- 如何从OA系统批量整理出邮箱地址,并导入到Foxmail 地址薄中?
一.打开某位leader的OA,点击查看“下属” a. 将所有的下属信息 --- 全选 --- 复制 --- 粘贴到 excel 表格中 b. 分别提取“姓名” 和 “邮箱”地址信息,结合notepa ...
- 腾讯云短信 nodejs 接入, 通过验证码修改手机示例
腾讯云短信 nodejs 接入, 通过验证码修改手机示例 参考:腾讯云短信文档国内短信快速入门qcloudsms Node.js SDK文档中心>短信>错误码 nodejs sdk 使用示 ...
- ireport初接触
我用的版本5.6.0 @官网下载地址 下载安装@参考博客龙凌云端,着重留意:在windows下使用,只下载iReport-5.6.0-windows-installer.exe就行了 安装后配置环境变 ...
- plsql if
set serveroutput on accept num prompt '请输入一个数字'; declare pnum number := # begin then dbms_ou ...