BZOJ3238 [Ahoi2013]差异
首先把后缀数组和height数组都搞出来。。。
然后用两个单调栈维护$[l, r]$表示对于一个点$x$,满足$height[x] \le height[l..x] \ \&\&\ height[x] < height[x..r]$的最小的$l$和最大的$r$
这样子就可以保证不会重复计算了
/**************************************************************
Problem: 3238
User: rausen
Language: C++
Result: Accepted
Time:4496 ms
Memory:20336 kb
****************************************************************/ #include <cstdio>
#include <cstring> using namespace std;
typedef long long ll;
const int N = 5e5 + ; int a[N], len;
int sa[N], rank[N], height[N]; inline void Sort(int *a, int *b, int *c, int n, int m) {
static int i, sum[N];
for (i = ; i <= m; ++i) sum[i] = ;
for (i = ; i < n; ++i) ++sum[c[a[i]]];
for (i = ; i <= m; ++i) sum[i] += sum[i - ];
for (i = n - ; ~i; --i)
b[--sum[c[a[i]]]] = a[i];
} void make_sa(int *s) {
int i, j;
static int x[N], y[N];
for (i = ; i < len; ++i) x[i] = s[i], rank[i] = i;
Sort(rank, sa, x, len, );
rank[sa[]] = ;
for (i = ; i < len; ++i)
rank[sa[i]] = rank[sa[i - ]] + (x[sa[i]] != x[sa[i - ]]);
for (i = ; i <= len; i <<= ) {
for (j = ; j < len; ++j)
x[j] = rank[j], y[j] = j + i < len ? rank[j + i] : , sa[j] = j;
Sort(sa, rank, y, len, len), Sort(rank, sa, x, len, len);
rank[sa[]] = ;
for (j = ; j < len; ++j)
rank[sa[j]] = rank[sa[j - ]] + (x[sa[j]] != x[sa[j - ]] || y[sa[j]] != y[sa[j - ]]);
if (rank[sa[len - ]] == len) return;
}
} void make_height() {
int i, j;
for (i = j = ; i < len; ++i) {
if (j) --j;
if (rank[i] != )
while (a[i + j] == a[sa[rank[i] - ] + j]) ++j;
height[rank[i]] = j;
}
} ll work() {
int i;
ll res;
static int s[N], top, l[N], r[N];
for (res = , i = ; i <= len; ++i) res += 1ll * i * (len - );
for (s[top = ] = , i = ; i <= len; ++i) {
while (height[i] <= height[s[top]] && top) --top;
l[i] = s[top] + ;
s[++top] = i;
}
for (s[top = ] = len + , i = len; i; --i) {
while (height[i] < height[s[top]] && top) --top;
r[i] = s[top] - ;
s[++top] = i;
}
for (i = ; i <= len; ++i)
res -= 2ll * (i - l[i] + ) * (r[i] - i + ) * height[i];
return res;
} int main() {
int i;
char ch;
for (len = ; ;) {
ch = getchar();
if ('a' <= ch && ch <= 'z') a[len++] = ch - 'a' + ;
else break;
}
make_sa(a);
make_height();
printf("%lld\n", work());
return ;
}
BZOJ3238 [Ahoi2013]差异的更多相关文章
- BZOJ3238 [Ahoi2013]差异 【SAM or SA】
BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单 ...
- 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$和显然 ...
- [BZOJ3238][AHOI2013]差异(后缀数组)
求和式的前两项可以直接算,问题是对于每对i,j计算LCP. 一个比较显然的性质是,LCP(i,j)是h[rk[i]+1~rk[j]]中的最小值. 从h的每个元素角度考虑,就是对每个h计算有多少对i,j ...
- [BZOJ3238][Ahoi2013]差异解题报告|后缀数组
Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首 ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
- BZOJ3238: [Ahoi2013]差异 (后缀自动机)
Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N< ...
- bzoj千题计划314:bzoj3238: [Ahoi2013]差异(后缀数组+st表+单调栈)
https://www.lydsy.com/JudgeOnline/problem.php?id=3238 跟 bzoj3879 差不多 #include<cstdio> #include ...
- 2018.12.21 bzoj3238: [Ahoi2013]差异(后缀自动机)
传送门 后缀自动机好题. 题意: 做法:samsamsam 废话 考虑翻转字串,这样后缀的最长公共前缀等于前缀的最长公共后缀. 然后想到parentparentparent树上面两个串的最长公共后缀跟 ...
随机推荐
- 发布《Linux工具快速教程》
发布<Linux工具快速教程> 阶段性的完成了这本书开源书籍,发布出来给有需要的朋友,同时也欢迎更多的朋友加入进来,完善这本书: 本书Github地址:https://github.com ...
- 复制选中的listbox内容
private void lt_log_MouseClick(object sender, MouseEventArgs e) { Clipboard.SetDataObject(lt_log.Sel ...
- LINQ之路 4:LINQ方法语法
书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询语法(Query Expression). LINQ方法语法是非常灵活和重要的,我们在这里将描述使用链接查询运算符的方 ...
- Thinkphp 3.2 添加 验证码 如何添加。
1,在home模块indexController.class.php中,加入以下代码 <?php namespace Home\Controller; use Think\Controller; ...
- mybatis的xml文件中如何处理大小于号
在mybatis的xml配置文件中会遇到大小于号转化的问题,解决问题的方法如下: 1.用转义字符把>和<替换掉 SELECT * FROM test WHERE AND start_dat ...
- linux学习笔记2-命令总结5
压缩解压命令 bzip2,gunzip,gzip,tar,zip 网络命令 ifconfig - 查看和配置网卡 lastlog - 检查某特定用户上次登录的时间 last - 列出目前和过去登入系统 ...
- mysql 有关的文件
1.在linux上安装好mysql之后,存在很多mysql有关的文件. 2./etc/rc.d/init.d/mysql 是mysql服务的启动脚本,是对mysqld_safe的封装,mysqld_s ...
- excel 里面拼接 MySQL insert 语句
="('"&A2&"',"&" '"&B2&"','"&C2&& ...
- [Selenium]点击Calendar控件后,Calendar dialog很快消失
有的日历控件使用了“opacity:0”透明度加上“display:none”来控制其是否显示,使用moveToElement方法不能移动到dialog上,可以把这两个属性的值进行修改,使其可见,使用 ...
- 开机使用root用户登录
有的fedora版本默认不支持开机以root用户登录,这是出于安全机制的考虑,可以通过设置实现开机root用户登录 步骤: 1.修改.etc/pam.d/gdm文件,注释掉auth pam_succ ...