题目链接

题目描述

给定一个长度为 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\) 来求

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define maxn 500010
  5. #define INF 1000000000
  6. #define ll long long
  7. using namespace std;
  8. int n;
  9. char c[maxn];
  10. int tax[maxn], rk[maxn], tp[maxn], sa[maxn], M = 200;
  11. void rsort() {
  12. for (int i = 0; i <= M; ++i) tax[i] = 0;
  13. for (int i = 1; i <= n; ++i) ++tax[rk[i]];
  14. for (int i = 1; i <= M; ++i) tax[i] += tax[i - 1];
  15. for (int i = n; i; --i) sa[tax[rk[tp[i]]]--] = tp[i];
  16. }
  17. int c1, H[maxn];
  18. void SA(char *s) {
  19. for (int i = 1; i <= n; ++i) rk[i] = s[i], tp[i] = i; rsort();
  20. for (int k = 1; k < n; k *= 2) {
  21. if (c1 == n) break; M = c1; c1 = 0;
  22. for (int i = n - k + 1; i <= n; ++i) tp[++c1] = i;
  23. for (int i = 1; i <= n; ++i) if (sa[i] > k) tp[++c1] = sa[i] - k;
  24. rsort(); swap(tp, rk); rk[sa[1]] = c1 = 1;
  25. for (int i = 2; i <= n; ++i) {
  26. if (tp[sa[i - 1]] != tp[sa[i]] || tp[sa[i - 1] + k] != tp[sa[i] + k]) ++c1;
  27. rk[sa[i]] = c1;
  28. }
  29. } int lcp = 0;
  30. for (int i = 1; i <= n; ++i) {
  31. if (lcp) --lcp;
  32. int j = sa[rk[i] - 1];
  33. while (s[j + lcp] == s[i + lcp]) ++lcp;
  34. H[rk[i]] = lcp;
  35. }
  36. }
  37. int st[maxn], top;
  38. ll ans, s;
  39. int main() {
  40. scanf("%s", c + 1); n = strlen(c + 1); SA(c); ans = (ll) n * (n - 1) / 2 * (n + 1);
  41. for (int i = 1; i < n; ++i) H[i] = H[i + 1]; H[n--] = 0;
  42. for (int i = 1; i <= n; ++i) {
  43. while (top && H[st[top]] >= H[i]) {
  44. s -= (ll) (st[top] - st[top - 1]) * H[st[top]];
  45. --top;
  46. }
  47. st[++top] = i; s += (st[top] - st[top - 1]) * H[st[top]];
  48. ans -= 2 * s;
  49. } cout << ans << endl;
  50. return 0;
  51. }

【后缀数组】【LuoguP4248】 [AHOI2013]差异的更多相关文章

  1. luoguP4248 [AHOI2013]差异

    题意 考虑式子前面那段其实是\((n-1)*\frac{n*(n+1)}{2}\),因为每个后缀出现了\(n-1\)次,后缀总长为\(\frac{n*(n+1)}{2}\). 现在考虑后面怎么求: \ ...

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

    BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...

  3. bzoj 3238: [Ahoi2013]差异 -- 后缀数组

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 一行,一个字符串S Output 一行,一个 ...

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

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

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

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

  6. [AHOI2013] 差异 - 后缀数组,单调栈

    [AHOI2013] 差异 Description 求 \(\sum {len(T_i) + len(T_j) - 2 lcp(T_i,T_j)}\) 的值 其中 \(T_i (i = 1,2,... ...

  7. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2326  Solved: 1054[Submit][Status ...

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

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

  9. 【bzoj3238】差异[AHOI2013](后缀数组+单调栈)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 这道题从大概半年以前就开始啃了,不过当时因为一些细节没调出来,看了Sakits神犇 ...

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

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

随机推荐

  1. mysql 复制表结构(包括索引等)、表内容

    =============================================== 2019/7/16_第1次修改                       ccb_warlock == ...

  2. Maven的仓库和settings.xml配置文件

    (尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_25827845/article/details/83549846冷血之心的博客) 快速导航: Maven基础概念和安 ...

  3. spring使用JUnit测试,@Autowired无法注入原因

    在测试类上加入配置文件 代码如下 @RunWith(SpringJUnit4ClassRunner.class)// SpringJUnit支持,由此引入Spring-Test框架支持!  @Cont ...

  4. Actions require unique method/path combination for Swagger

    原文:Actions require unique method/path combination for Swagger services.AddSwaggerGen (c => { c.Re ...

  5. MySQL数据库基本规范整理

    此篇文章是学习MySQL技术整理的,不足之处还望指教,不胜感激. 数据库基本规范涉及数据库命名规范.数据库索引设计规范.数据库基本设计规范.数据库字段设计规范.数据库SQL开发规范.数据库操作行为规范 ...

  6. pandas-08 pd.cut()的功能和作用

    pandas-08 pd.cut()的功能和作用 pd.cut()的作用,有点类似给成绩设定优良中差,比如:0-59分为差,60-70分为中,71-80分为优秀等等,在pandas中,也提供了这样一个 ...

  7. 用jQuery的toggle方法实现元素的左右滑动隐藏

    通常情况下给元素加toggle方法通常会是上下滑动隐藏,而有时我们又需要左右滑动隐藏怎么办呢 $(document).ready(function(){ $('#example').click(fun ...

  8. php长连接应用

    php长连接和短连接 2012-12-05 17:25 3529人阅读 评论(0) 收藏 举报  分类: 我的收藏(8)  什么是长连接,如果你没听说过,可以往下看! 长连接到底有什么用?我想你应该见 ...

  9. VUE基础回顾2

    1.响应式 vue修改了每个添加到data上的对象,当该对象发生变化时vue会收到通知,从而实现响应式.对象的每个属性都会被替换为getter,setter方法. 有两种方式实现data对象的监听 ( ...

  10. region、xld有对应的字符串时,将region、xld按照行或列排序的算法实现

    用Halcon解码时,如果一张图里面有多个码,它通常可以把这些码都解出来,并且生成对应的解码结果字符串元组(也就是下面的DecodedDataStrings),如果有多个码,那么该元组就有多个元素. ...