【后缀数组】【LuoguP4248】 [AHOI2013]差异
题目描述
给定一个长度为 n 的字符串 S,令 Ti 表示它从第 i 个字符开始的后缀。求
\(\sum_{1\le i <j\le n}len(T_i)+len(T_j)-2*lcp(T_i,T_j)\)
说明
对于 100% 的数据,保证 2⩽n⩽500000,且均为小写字母。
思路
注意到前面那个东西是个定值,所以关键在于如何求后面那个东西
由于 \(lcp(sa[l],sa[r])=min_{i=l+1}^{r}H[i]\)
所以后面那个东西实际上就是 \(H\) 数组的所有子区间 \(min\) 之和,当然是去掉 \(H[1]\) 之后
这个东西可以用单调栈通过维护后缀 \(min\) 来求
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 500010
#define INF 1000000000
#define ll long long
using namespace std;
int n;
char c[maxn];
int tax[maxn], rk[maxn], tp[maxn], sa[maxn], M = 200;
void rsort() {
for (int i = 0; i <= M; ++i) tax[i] = 0;
for (int i = 1; i <= n; ++i) ++tax[rk[i]];
for (int i = 1; i <= M; ++i) tax[i] += tax[i - 1];
for (int i = n; i; --i) sa[tax[rk[tp[i]]]--] = tp[i];
}
int c1, H[maxn];
void SA(char *s) {
for (int i = 1; i <= n; ++i) rk[i] = s[i], tp[i] = i; rsort();
for (int k = 1; k < n; k *= 2) {
if (c1 == n) break; M = c1; c1 = 0;
for (int i = n - k + 1; i <= n; ++i) tp[++c1] = i;
for (int i = 1; i <= n; ++i) if (sa[i] > k) tp[++c1] = sa[i] - k;
rsort(); swap(tp, rk); rk[sa[1]] = c1 = 1;
for (int i = 2; i <= n; ++i) {
if (tp[sa[i - 1]] != tp[sa[i]] || tp[sa[i - 1] + k] != tp[sa[i] + k]) ++c1;
rk[sa[i]] = c1;
}
} int lcp = 0;
for (int i = 1; i <= n; ++i) {
if (lcp) --lcp;
int j = sa[rk[i] - 1];
while (s[j + lcp] == s[i + lcp]) ++lcp;
H[rk[i]] = lcp;
}
}
int st[maxn], top;
ll ans, s;
int main() {
scanf("%s", c + 1); n = strlen(c + 1); SA(c); ans = (ll) n * (n - 1) / 2 * (n + 1);
for (int i = 1; i < n; ++i) H[i] = H[i + 1]; H[n--] = 0;
for (int i = 1; i <= n; ++i) {
while (top && H[st[top]] >= H[i]) {
s -= (ll) (st[top] - st[top - 1]) * H[st[top]];
--top;
}
st[++top] = i; s += (st[top] - st[top - 1]) * H[st[top]];
ans -= 2 * s;
} cout << ans << endl;
return 0;
}
【后缀数组】【LuoguP4248】 [AHOI2013]差异的更多相关文章
- luoguP4248 [AHOI2013]差异
题意 考虑式子前面那段其实是\((n-1)*\frac{n*(n+1)}{2}\),因为每个后缀出现了\(n-1\)次,后缀总长为\(\frac{n*(n+1)}{2}\). 现在考虑后面怎么求: \ ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...
- bzoj 3238: [Ahoi2013]差异 -- 后缀数组
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...
- 【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈
[BZOJ3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...
- [bzoj3238][Ahoi2013]差异_后缀数组_单调栈
差异 bzoj-3238 Ahoi-2013 题目大意:求任意两个后缀之间的$LCP$的和. 注释:$1\le length \le 5\cdot 10^5$. 想法: 两个后缀之间的$LCP$和显然 ...
- [AHOI2013] 差异 - 后缀数组,单调栈
[AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...
- BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2326 Solved: 1054[Submit][Status ...
- [BZOJ3238][Ahoi2013]差异解题报告|后缀数组
Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首 ...
- 【bzoj3238】差异[AHOI2013](后缀数组+单调栈)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 这道题从大概半年以前就开始啃了,不过当时因为一些细节没调出来,看了Sakits神犇 ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
随机推荐
- python安装和pycharm安装与笔记
目录 计算机的基础知识 python安装和使用 pycharm安装和使用 [TOC] 计算机的基础知识 计算机是由什么组成的 cpu-----大脑 主板----身体 电源----心脏 内存----临时 ...
- 【MySQL】数据库中间件Atlas
1.介绍 Atlas 是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目.它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改 ...
- CSS3 小黄人案例
使用 CSS3 和 HTML5 制作一个小黄人. 结构代码: <div class="wrap"> <!-- 头发 --> <div class=&q ...
- JavaWeb 之 Filter 验证用户登录案例
需求: 1. 访问一个网站的资源.验证其是否登录 2. 如果登录了,则直接放行. 3. 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录". 代码实现: import j ...
- Js 打印 div
var wind = window.open("", 'newwindow', 'height=700, width=1000, top=100, left=100, toolba ...
- Iris Network Traffic Analyzer嗅探器
网卡配置 ftp测试
- 在centOS 7 上部署ansible自动化运维环境(01)
环境: 3台centos 7 mycat : 10.0.0.2 mariadb1: 10.0.0.3 mariadb2: 10.0.0.4 为了实验方便 f ...
- github hooks 配置教程 钩子搭建(实测通过,手把手教程)
tips:如果本文对你有用,请爱心点个赞,提高排名,让这篇文章帮助更多的人.谢谢大家!❤ 本人hooks搭建成功,全程参考JellyBool老师的视频教程,有不懂的可以先去看下这个视频,跟着操作.本文 ...
- Android笔记(七十六) 点菜DEMO
一个朋友让看一下他的代码,一个点菜的功能,他和我一样,初学者,代码比我的都混乱,也是醉了,干脆想着自己写个demo给他看,原本想着听简单,半个小时应该就可以搞定,真正写的时候,画了3h+,汗颜... ...
- MySQL用户与权限
用户连接到mysql,并做各种查询,在用户和服务器中间分为两个阶段: 1:用户是否有权连接上来 2:用户是否有权执行此操作(如select,update等等) 先看第一个阶段:服务器如何判断用户是否有 ...