首先把后缀数组和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]差异的更多相关文章

  1. BZOJ3238 [Ahoi2013]差异 【SAM or SA】

    BZOJ3238 [Ahoi2013]差异 给定一个串,问其任意两个后缀的最长公共前缀长度的和 1.又是后缀,又是\(lcp\),很显然直接拿\(SA\)的\(height\)数组搞就好了,配合一下单 ...

  2. bzoj3238 [Ahoi2013]差异 后缀数组+单调栈

    [bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  3. [bzoj3238][Ahoi2013]差异_后缀数组_单调栈

    差异 bzoj-3238 Ahoi-2013 题目大意:求任意两个后缀之间的$LCP$的和. 注释:$1\le length \le 5\cdot 10^5$. 想法: 两个后缀之间的$LCP$和显然 ...

  4. [BZOJ3238][AHOI2013]差异(后缀数组)

    求和式的前两项可以直接算,问题是对于每对i,j计算LCP. 一个比较显然的性质是,LCP(i,j)是h[rk[i]+1~rk[j]]中的最小值. 从h的每个元素角度考虑,就是对每个h计算有多少对i,j ...

  5. [BZOJ3238][Ahoi2013]差异解题报告|后缀数组

    Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首 ...

  6. BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】

    题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...

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

    Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N< ...

  8. bzoj千题计划314:bzoj3238: [Ahoi2013]差异(后缀数组+st表+单调栈)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3238 跟 bzoj3879 差不多 #include<cstdio> #include ...

  9. 2018.12.21 bzoj3238: [Ahoi2013]差异(后缀自动机)

    传送门 后缀自动机好题. 题意: 做法:samsamsam 废话 考虑翻转字串,这样后缀的最长公共前缀等于前缀的最长公共后缀. 然后想到parentparentparent树上面两个串的最长公共后缀跟 ...

随机推荐

  1. MongoDB 中遇到的一些错误

    1.在win平台上,使用ctrl+c关闭mongodb后,使用 mongod --dbpath=D:\mongodb\db --logpath=D:\mongodb\log.txt --port -- ...

  2. POJ-2175 Evacuation Plan 最小费用流、负环判定

    题意:给定一个最小费用流的模型,根据给定的数据判定是否为最优解,如果不为最优解则给出一个比给定更优的解即可.不需要得出最优解. 解法:由给定的数据能够得出一个残图,且这个图满足了最大流的性质,判定一个 ...

  3. EF中使用SQL语句或存储过程(小笔记)

    1.无参数查询 var model = db.Database.SqlQuery<UserInfo>("select* from UserInfoes ").ToLis ...

  4. js模块化编程总结

    大家都知道,js中的变量(variable)有其作用范围,比如:函数里用var定义的变量在函数外是看不到的,而定义在函数外面的变量(不能有没有var修饰)均是全局变量,在js程序的任何位置都可以访问. ...

  5. 用Jquery获取select的value和text值

    $("#select_id").change(function(){//code...}); //为Select添加事件,当选择其中一项时触发 var checkText=$(&q ...

  6. HTML <meta> 标签

    <meta> 元素可提供有关页面的元信息,元数据总是以名称/值的形式被成对传递的. <meta> 标签位于文档的头部,不包含任何内容. <meta> 标签的属性定义 ...

  7. Linux之top命令

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法.top是一个动态显示过程,即可以通过用户按键来不断刷新 ...

  8. javascript------>(此文转发)

    JS控制div跳转到指定的位置的解决方案总结   总结一下自己在写这个需求遇到的问题,相信大家应该是经常遇到的.即要求滚轮滚动到指定的位置.先看下基本的解决方案. 1.给链接a加个#的方式来实现跳转. ...

  9. 机器学习如何选择模型 & 机器学习与数据挖掘区别 & 深度学习科普

    今天看到这篇文章里面提到如何选择模型,觉得非常好,单独写在这里. 更多的机器学习实战可以看这篇文章:http://www.cnblogs.com/charlesblc/p/6159187.html 另 ...

  10. ResponseUtil反射制造唯一结果

    调用:通过反射调用同一个类型的返回值 return fillResponse(response,Constants.SUCCESS,"获取数据成功","taskList& ...