题意:求所有后缀两两之间的最长公共前缀的长度之和。

解:这道题让我发现了一个奇妙的性质:所有后缀两两最长公共前缀长度之和 和 所有前缀两两最长公共后缀之和的值是相等的,但是每一组公共前/后缀是不同的。

因为这道题要反建后缀自动机,我正建然后过了......

两个串的最长公共后缀就是在fail树上的lca。

所以反建后缀自动机,所有后缀就是主链。然后求这些两两的lca计算每个点作为lca被统计了多少次,树上DFS一遍就好了。

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4.  
  5. typedef long long LL;
  6. const int N = ;
  7.  
  8. struct Edge {
  9. int nex, v;
  10. }edge[N]; int top;
  11.  
  12. int tr[N][], len[N], fail[N], cnt[N], tot = , last = ;
  13. int e[N], siz[N];
  14. LL ans;
  15. char s[N];
  16.  
  17. inline void add(int x, int y) {
  18. top++;
  19. edge[top].v = y;
  20. edge[top].nex = e[x];
  21. e[x] = top;
  22. return;
  23. }
  24.  
  25. inline void insert(char c) {
  26. int f = c - 'a';
  27. int p = last, np = ++tot;
  28. last = np;
  29. len[np] = len[p] + ;
  30. cnt[np] = ;
  31. while(p && !tr[p][f]) {
  32. tr[p][f] = np;
  33. p = fail[p];
  34. }
  35. if(!p) {
  36. fail[np] = ;
  37. }
  38. else {
  39. int Q = tr[p][f];
  40. if(len[Q] == len[p] + ) {
  41. fail[np] = Q;
  42. }
  43. else {
  44. int nQ = ++tot;
  45. len[nQ] = len[p] + ;
  46. fail[nQ] = fail[Q];
  47. fail[Q] = fail[np] = nQ;
  48. memcpy(tr[nQ], tr[Q], sizeof(tr[Q]));
  49. while(tr[p][f] == Q) {
  50. tr[p][f] = nQ;
  51. p = fail[p];
  52. }
  53. }
  54. }
  55. return;
  56. }
  57.  
  58. inline void prework() {
  59. for(int i = ; i <= tot; i++) {
  60. add(fail[i], i);
  61. //printf("add : %d %d \n", fail[i], i);
  62. }
  63. return;
  64. }
  65.  
  66. void DFS(int x) {
  67. siz[x] = cnt[x];
  68. for(int i = e[x]; i; i = edge[i].nex) {
  69. int y = edge[i].v;
  70. DFS(y);
  71. if(x > ) {
  72. ans += 1ll * siz[x] * siz[y] * len[x];
  73. }
  74. siz[x] += siz[y];
  75. }
  76. //printf("x = %d siz = %d \n", x, siz[x]);
  77. return;
  78. }
  79.  
  80. int main() {
  81. LL sum = ;
  82. scanf("%s", s);
  83. int n = strlen(s);
  84. for(int i = ; i < n; i++) {
  85. insert(s[i]);
  86. sum += 1ll * (n - ) * (i + );
  87. }
  88. prework();
  89. DFS();
  90. printf("%lld\n", sum - * ans);
  91. //printf("%lld - %lld \n", sum, 2 * ans);
  92. return ;
  93. }

AC代码(伪)

洛谷P4248 差异的更多相关文章

  1. 洛谷 P4248: bzoj 3238: [AHOI2013]差异

    题目传送门:洛谷 P4248. 题意简述: 定义两个字符串 \(S\) 和 \(T\) 的差异 \(\operatorname{diff}(S,T)\) 为这两个串的长度之和减去两倍的这两个串的最长公 ...

  2. 洛谷P4248 [AHOI2013]差异(后缀自动机求lcp之和)

    题目见此 题解:首先所有后缀都在最后一个np节点,然后他们都是从1号点出发沿一些字符边到达这个点的,所以下文称1号点为根节点,我们思考一下什么时候会产生lcp,显然是当他们从根节点开始一直跳相同节点的 ...

  3. 洛谷 P4248 / loj 2377 [AHOI2013] 差异 题解【后缀自动机】【树形DP】

    可能是一个 SAM 常用技巧?感觉 SAM 的基础题好多啊.. 题目描述 给定一个长度为 \(n\) 的字符串 \(S\) ,令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀,求: \[ ...

  4. [洛谷P4248][AHOI2013]差异

    题目大意:给一个长度为$n$的字符串,求: $$\sum\limits_{1\leqslant i<j\leqslant n}|suf_i|+|suf_j|-2\times lcp(suf_i, ...

  5. 【洛谷 P4248】 [AHOI2013]差异(后缀自动机)

    题目链接 \[ans=\sum_{1<=i<j<=n}len(T_i)+len(T_j)-2*lcp(T_i,T_j)\] 观察这个式子可以发现,前面两个\(len\)是常数,后面的 ...

  6. 洛谷P3348 [ZJOI2016]大森林(LCT,虚点,树上差分)

    洛谷题目传送门 思路分析 最简单粗暴的想法,肯定是大力LCT,每个树都来一遍link之类的操作啦(T飞就不说了) 考虑如何优化算法.如果没有1操作,肯定每个树都长一样.有了1操作,就来仔细分析一下对不 ...

  7. c++并查集配合STL MAP的实现(洛谷P2814题解)

    不会并查集的话请将此文与我以前写的并查集一同食用. 原题来自洛谷 原题 文字稿在此: 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. ...

  8. NOI2006 最大获利 洛谷P4174

    洛谷题目传送门! 题目描述 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU 集团旗下的 CS&T 通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就 ...

  9. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

随机推荐

  1. unsupported time zone specified undefined

    unsupported time zone specified undefined   出现了这个问题,莫名其妙的,上次被我下回去了,真的是下回去的,我一去查看,坐在电脑前面问题就不见了…… 具体出现 ...

  2. Django--ORM 多表查询

    一 . 建立外键 一对一建立外键 外键名称 = models.OneToOneField(to='要连接的类名', to_field='字段') 一对多建立外键 外键名称 = models.Forei ...

  3. python之路--前端CSS

    一.CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义了如何显示HTML元素,给HTML设置样式,让他更加美观. 当浏览器读到这个样式表, 他就会按照这个样式来对文档进行 ...

  4. elasticsearch介绍,安装,安装错误解决及相应插件安装

    一.elasticsearch介绍 1.简介(使用的是nosql,更新比mongodb慢): ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎, ...

  5. spring 注解 之 AOP基于@Aspect的AOP配置

    Spring AOP面向切面编程,可以用来配置事务.做日志.权限验证.在用户请求时做一些处理等等.用@Aspect做一个切面,就可以直接实现. 1.首先定义一个切面类,加上@Component  @A ...

  6. shit iview docs & i-radio bug

    shit iview docs & i-radio bug https://github.com/iview/iview/issues/5627 <i-row> <i-col ...

  7. JQ查找到带有某个字符,并起类名,然后替换这个某个字符

    <script> setTimeout("asdasd()",1000); //定时器是为了防止其他JS影响到它,可以不加 function asdasd() { $( ...

  8. 关于浏览器兼容问题——还有移动端meta问题

    <!DOCTYPE html><!--[if lt IE 7]> <html dir="ltr" lang="en-US" cla ...

  9. Delphi 在dbgrideh中表格输入数据时有效性的检查(转)

    在数据库系统设计中经常要用到在表格中进行数据录入,如何判断在数据导入时的数据有效性呢?下面介绍几种常用的方法与大家交流. 方法一:Dbgrid是与Table,在Table的Column的OnSetTe ...

  10. Nginx 用最快方式让缓存失效

    陶辉103 一般让及时缓存失效针对nginx官方是收费的 我们可以用第三方模块 https://github.com/FRiCKLE/ngx_cache_purge proxy_cache_path ...