[传送门[(https://www.lydsy.com/JudgeOnline/problem.php?id=3238)

解题思路

  首先原式可以把\(len\)那部分直接算出来,然后通过后缀数组求\(lcp\)。算\(\sum lcp\)的时候,刚开始傻了想要直接算贡献,结果越写越乱,后来想想只需要用单调栈把每个点的控制范围算出来即可,正着做一遍反着做一遍。注意还要考虑两个\(h[i]\)相邻并相等时的影响。还有一种比较自然的解法是后缀树,\(lcp\)其实就为两个点的\(lca\)的深度,所以建出后缀树后直接按拓扑序\(dp\)一下即可。

代码

后缀数组:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cstdlib>
  5. using namespace std;
  6. const int MAXN = 500005;
  7. typedef long long LL;
  8. int n,m,height[MAXN],num,stk[MAXN],top,l[MAXN],r[MAXN];
  9. int sa[MAXN],rk[MAXN],x[MAXN<<1],y[MAXN<<1],c[MAXN];
  10. char s[MAXN];
  11. LL ans;
  12. inline void get_SA(){
  13. for(int i=1;i<=n;i++) x[i]=s[i],c[x[i]]++;
  14. for(int i=2;i<=m;i++) c[i]+=c[i-1];
  15. for(int i=n;i;i--) sa[c[x[i]]--]=i;
  16. for(int k=1;k<=n;k<<=1){num=0;
  17. for(int i=n-k+1;i<=n;i++) y[++num]=i;
  18. for(int i=1;i<=n;i++) if(sa[i]>k) y[++num]=sa[i]-k;
  19. memset(c,0,sizeof(c));
  20. for(int i=1;i<=n;i++) c[x[i]]++;
  21. for(int i=2;i<=m;i++) c[i]+=c[i-1];
  22. for(int i=n;i;i--) sa[c[x[y[i]]]--]=y[i],y[i]=0;
  23. swap(x,y);num=1;x[sa[1]]=1;
  24. for(int i=2;i<=n;i++)
  25. x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
  26. if(num==n) break;m=num;
  27. }
  28. }
  29. inline void get_height(){
  30. for(int i=1;i<=n;i++) rk[sa[i]]=i;int j,k=0;
  31. for(int i=1;i<=n;i++){
  32. if(rk[i]==1) continue;
  33. if(k) k--;j=sa[rk[i]-1];
  34. while(i+k<=n && j+k<=n && s[i+k]==s[j+k]) k++;
  35. height[rk[i]]=k;
  36. }
  37. }
  38. void solve(){
  39. for(int i=1;i<=n;i++){
  40. while(top && height[i]<=height[stk[top]]) l[stk[top]]=i-1,top--;
  41. if(height[i]) stk[++top]=i;
  42. }
  43. while(top) l[stk[top--]]=n;
  44. for(int i=n;i;i--){
  45. while(top && height[i]<height[stk[top]]) r[stk[top]]=i+1,top--;
  46. if(height[i]) stk[++top]=i;
  47. }
  48. while(top) r[stk[top--]]=1;
  49. for(int i=1;i<=n;i++) ans-=(LL)height[i]*(l[i]-i+1)*(i-r[i]+1)*2;
  50. }
  51. int main(){
  52. scanf("%s",s+1);n=strlen(s+1);m='z';
  53. get_SA();get_height();
  54. // for(int i=1;i<=n;i++) cout<<sa[i]<<" ";cout<<endl;
  55. // for(int i=1;i<=n;i++) cout<<height[i]<<" ";cout<<endl;
  56. ans=(LL)n*(n-1)/2*(n+1);
  57. solve();printf("%lld\n",ans);
  58. return 0;
  59. }

后缀树:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<cstdlib>
  6. #define int long long
  7. using namespace std;
  8. const int MAXN = 500005<<1;
  9. typedef long long LL;
  10. char s[MAXN];
  11. int n,siz[MAXN],lst,cnt;
  12. int fa[MAXN],ch[MAXN][27],l[MAXN],a[MAXN],c[MAXN];
  13. LL ans;
  14. inline void Insert(int c){
  15. int p=lst,np=++cnt;lst=np;l[np]=l[p]+1;
  16. for(;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
  17. if(!p) fa[np]=1;
  18. else{
  19. int q=ch[p][c];
  20. if(l[q]==l[p]+1) fa[np]=q;
  21. else {
  22. int nq=++cnt;l[nq]=l[p]+1;
  23. memcpy(ch[nq],ch[q],sizeof(ch[q]));
  24. fa[nq]=fa[q];fa[q]=fa[np]=nq;
  25. for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
  26. }
  27. }
  28. siz[np]=1;
  29. }
  30. signed main(){
  31. scanf("%s",s+1);n=strlen(s+1);lst=cnt=1;
  32. for(int i=n;i;i--) Insert(s[i]-'a'+1);
  33. ans=(LL)n*(n-1)/2*(n+1);
  34. for(int i=1;i<=cnt;i++) c[l[i]]++;
  35. for(int i=1;i<=cnt;i++) c[i]+=c[i-1];
  36. for(int i=1;i<=cnt;i++) a[c[l[i]]--]=i;
  37. for(int i=cnt;i;i--){
  38. ans-=(LL)siz[a[i]]*siz[fa[a[i]]]*l[fa[a[i]]]*2;
  39. siz[fa[a[i]]]+=siz[a[i]];
  40. }
  41. printf("%lld\n",ans);
  42. return 0;
  43. }

BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))的更多相关文章

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

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

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

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

  3. BZOJ 3238: [Ahoi2013]差异 [后缀自动机]

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

  4. bzoj 3238 Ahoi2013 差异

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

  5. BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)

    题目链接 \(Description\) \(Solution\) len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次. \[\sum_{i=1}^n\sum_{j=i+1 ...

  6. ●BZOJ 3238 [Ahoi2013]差异

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3238 题解: 后缀数组套路深. 问题转化为求出任意两个后缀的LCP之和 在计算贡献时,各种不 ...

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

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

  8. BZOJ 4826: [Hnoi2017]影魔 单调栈+可持久化线段树

    Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个 ...

  9. BZOJ 3238 [Ahoi2013]差异(后缀自动机)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3238 [题目大意] 给出一个串,设T[i]表示从第i位开始的后缀, 求sum(len( ...

随机推荐

  1. QT blockingmaster例子学习

    dialog.h: #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include "masterthread.h&q ...

  2. hdu1574 I Hate It (线段树,查询区间最大值)

    Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟 ...

  3. paper 134:结构张量structure tensor(二)

    根据结构张量能区分图像的平坦区域.边缘区域与角点区域. 此算法也算是计算机科学最重要的32个算法之一了.链接的文章中此算法名称为Strukturtensor算法,不过我搜索了一下,Strukturte ...

  4. delphi 获取系统注册的文件图标

    var Icon:TICON; Key : string; App : string; Index : Integer; begin FileName:=Edit6.Text; then begin ...

  5. pycharm 代码无法自动补全(自动顺带)的解决方法

    pycharm 中输入关键字等,代码不能自动补全,这种情况一般是pycharm设置了省电模式 点击 File —Power Save Mode,取消勾选 再次输入,代码可以自动顺带出来了

  6. 【Java架构:基础技术】一篇文章搞掂:Idea

    一.使用技巧 1.1.配置Maven 打开File-Settings打开设置界面 1.2.配置JDK JDK可以设置默认版本,也可以设置针对某个项目 分别对应File-Other Setting-De ...

  7. error LNK2005: __get_invalid_parameter_handler 已经在 LIBCMTD.lib(invarg.obj) 中定义

    转自VC错误http://www.vcerror.com/?p=166 问题描述: 在用vs2012编译程序的时候,release版本正常编译通过,但Debug版本提示下面的很多错误; 1>LI ...

  8. Java学习之Static

    Static(静态)是一种修饰符,用于修饰成员(成员变量.成员函数) 1.静态方法只能访问静态成员. 2.静态随着类的加载而加载 通过代码分析: class PersonDemo { public s ...

  9. 28. Python编写自动化测试用例

    接口文档已经提供了,requests库.unittest单元测试框架也已经介绍过,笔者相信读者朋友已经可以独立编写接口自动化测试用例了.但是有一些细节,我们需要聊一下.比如我们写登录接口测试用例,用户 ...

  10. Cocos2d-x在Windows平台环境的搭建

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. windows平台下配置Cocos2d-X引擎所需的压缩文件和可执行文件,如下: 下载链接: adt:    http://tools.a ...