题目链接

给定两个字符串,求它们有多少个相同子串。相同串的位置不同算多个。

POJ3145简化版。

后缀自动机做法见这儿,又快又好写(一下就看出差距了。。)

  1. //13712kb 4076ms
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. const int N=4e5+5;
  6. int n,rk[N],sa[N],sa2[N],tm[N],ht[N],bel[N],sk[N],val[N];
  7. char s[N];
  8. void Get_SA()
  9. {
  10. int *x=rk,*y=sa2,m=30;
  11. for(int i=0; i<=m; ++i) tm[i]=0;
  12. for(int i=1; i<=n; ++i) ++tm[x[i]=s[i]-'a'+2];
  13. for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
  14. for(int i=n; i; --i) sa[tm[x[i]]--]=i;
  15. for(int p=0,k=1; k<n; m=p,p=0,k<<=1)
  16. {
  17. for(int i=n-k+1; i<=n; ++i) y[++p]=i;
  18. for(int i=1; i<=n; ++i) if(sa[i]>k) y[++p]=sa[i]-k;
  19. for(int i=0; i<=m; ++i) tm[i]=0;
  20. for(int i=1; i<=n; ++i) ++tm[x[i]];
  21. for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
  22. for(int i=n; i; --i) sa[tm[x[y[i]]]--]=y[i];
  23. std::swap(x,y), p=x[sa[1]]=1;
  24. for(int i=2; i<=n; ++i)
  25. x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?
  26. p:++p;
  27. if(p>=n) break;
  28. }
  29. for(int i=1; i<=n; ++i) rk[sa[i]]=i;
  30. ht[1]=0;
  31. for(int k=0,p,i=1; i<=n; ++i)
  32. {
  33. if(rk[i]==1) continue;
  34. if(k) --k;
  35. p=sa[rk[i]-1];
  36. while(i+k<=n&&p+k<=n&&s[i+k]==s[p+k]) ++k;
  37. ht[rk[i]]=k;
  38. }
  39. }
  40. int main()
  41. {
  42. scanf("%s",s+1); int l=strlen(s+1);
  43. s[l+1]='a'-1, scanf("%s",s+2+l), n=strlen(s+1);
  44. Get_SA();
  45. for(int i=2; i<=n; ++i) bel[i]=sa[i]>l;
  46. long long res=0,tmp;
  47. val[0]=-1;
  48. for(int top,t=0; t<=1; ++t)
  49. {
  50. tmp=0, top=0;
  51. for(int i=2; i<=n; ++i)
  52. {
  53. if(bel[i]!=t) res+=tmp;
  54. sk[++top]=bel[i]==t, val[top]=ht[i+1];
  55. tmp+=(long long)sk[top]*val[top];
  56. while(val[top-1]>=val[top])//>=比>要快啊
  57. {
  58. --top;
  59. tmp-=(long long)(val[top]-val[top+1])*sk[top];
  60. val[top]=val[top+1], sk[top]+=sk[top+1];
  61. }
  62. }
  63. }
  64. printf("%lld",res);
  65. return 0;
  66. }

BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)的更多相关文章

  1. [HAOI2016] 找相同字符 - 后缀数组,单调栈

    [HAOI2016] 找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. \(n,m \l ...

  2. 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈

    [BZOJ4566][Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...

  3. BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 275  Solved: 155[Submit][Statu ...

  4. bzoj 4566 [Haoi2016]找相同字符SA

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 128  Solved: 75[Submit][Status ...

  5. 【刷题】BZOJ 4566 [Haoi2016]找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别为 ...

  6. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  7. bzoj 4199: [Noi2015]品酒大会【后缀数组+单调栈+并查集】

    用SA求出height数组,然后发现每个height值都有一个贡献区间(因为点对之间要依次取min) 用单调栈处理出区间,第一问就做完了 然后用并查集维护每个点的贡献(?),从大到小枚举height, ...

  8. bzoj 4566 [Haoi2016]找相同字符——广义后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 每个后缀结尾处 ct[ ] = 1 ,按拓扑序 dp 一下就能求出 right 集合的 ...

  9. BZOJ 4566 [Haoi2016]找相同字符 ——广义后缀自动机

    建立广义后缀自动机. 然后统计子树中的siz,需要分开统计 然后对(l[i]-l[fa[i]])*siz[i][0]*siz[i][1]求和即可. #include <cstdio> #i ...

随机推荐

  1. 【转】assert预处理宏与预处理变量

    assert assert是一个预处理宏,由预处理器管理而非编译器管理,所以使用时都不用命名空间声明,如果你写成std::assert反而是错的.使用assert需要包含cassert或assert. ...

  2. C++编程命名规则

    原文地址:http://www.cnblogs.com/ggjucheng/archive/2011/12/15/2289291.html 如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套 ...

  3. phpstudy中apache的默认根目录的配置

    默认配置文件是:vhosts.conf. 安装laravel后需要把根目录配置到public. 下面的配置需要在本地计算机的host文件配置域名,一个是“localhost”,一个是“www.goho ...

  4. ubuntu系统初始化网络及mysql配置

    安装系统时需要安装open-ssh服务软件,否则无法远程连接 1.修改root密码 # sudo passwd 输入密码即可 切换到root用户,需要输入刚才的root密码 # su - 2.配置网络 ...

  5. webpack中的output.filename 和output.chunkFilename

    filename应该比较好理解,就是对应于entry里面生成出来的文件名.比如: { entry: { "index": "pages/index.jsx" } ...

  6. 【ES】match_phrase与regexp

    刚开始接触es,由于弄不清楚match_phrase和regexp导致很多查询结果与预想的不同.在这整理一下. regexp:针对的是单个词项 match_phrase:针对的是多个词项的相对位置 它 ...

  7. spoj227 树状数组插队序列问题

    插队问题和线段树解决的方式一样,每个结点维护值的信息是该节点之前的空位有多少,然后从后往前插点即可 注意该题要求输出的是从左往右输出每个士兵的等级,即问士兵最后排在第几个位置 /* 树状数组维护前i个 ...

  8. python 全栈开发,Day104(DRF用户认证,结算中心,django-redis)

    考试第二部分:MySQL数据库 6.  MySQL中char和varchar的区别(1分) char是定长,varchar是变长. char的查询速度比varchar要快. 7.   MySQL中va ...

  9. 实现与JS相同的Des加解密算法【转】

    Java代码 import java.util.ArrayList; import java.util.List; /** * DES加密/解密 * * @Copyright Copyright (c ...

  10. 《Java程序性能优化》之设计优化

    豆瓣读书:http://book.douban.com/subject/19969386/ 第一章 Java性能调优概述 1.性能的参考指标 执行时间: CPU时间: 内存分配: 磁盘吞吐量: 网络吞 ...