【BZOJ4566】[Haoi2016]找相同字符

Description

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

Input

两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1, n2<= 200000,字符串中只有小写字母

Output

输出一个整数表示答案

Sample Input

aabb
bbaa

Sample Output

10

题解:本题跟差异那道题很相似,理论上可以直接一遍sa搞定,但是我比较懒,直接求了3遍sa。

子串相同的方案数=后缀的相同前缀长度总和,两个串的相同后缀长度总和=两个串连一起的总和-两个串内部的长度和

具体做法请见差异

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. using namespace std;
  5. const int maxn=400010;
  6. int n,m,len1,len2;
  7. int r[maxn],ra[maxn],rb[maxn],st[maxn],sa[maxn],h[maxn],rank[maxn];
  8. int q[maxn],t,ls[maxn],rs[maxn];
  9. long long ans,sum;
  10. char s1[maxn],s2[maxn];
  11. void work()
  12. {
  13. int i,j,k,*x=ra,*y=rb,p;
  14. for(i=0;i<m;i++) st[i]=0;
  15. for(i=0;i<n;i++) st[x[i]=r[i]]++;
  16. for(i=1;i<m;i++) st[i]+=st[i-1];
  17. for(i=n-1;i>=0;i--) sa[--st[x[i]]]=i;
  18. for(p=j=1;p<n;j<<=1,m=p)
  19. {
  20. for(p=0,i=n-j;i<n;i++) y[p++]=i;
  21. for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
  22. for(i=0;i<m;i++) st[i]=0;
  23. for(i=0;i<n;i++) st[x[y[i]]]++;
  24. for(i=1;i<m;i++) st[i]+=st[i-1];
  25. for(i=n-1;i>=0;i--) sa[--st[x[y[i]]]]=y[i];
  26. for(swap(x,y),x[sa[0]]=0,i=p=1;i<n;i++)
  27. x[sa[i]]=(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j])?p-1:p++;
  28. }
  29. for(i=1;i<n;i++) rank[sa[i]]=i;
  30. for(i=k=0;i<n-1;h[rank[i++]]=k)
  31. for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
  32. sum=0,t=0,h[0]=h[n]=-1;
  33. for(i=1;i<=n;i++)
  34. {
  35. while(t&&h[q[t]]>=h[i]) rs[q[t--]]=i;
  36. q[++t]=i;
  37. }
  38. t=0;
  39. for(i=n-1;i>=0;i--)
  40. {
  41. while(t&&h[q[t]]>h[i]) ls[q[t--]]=i;
  42. q[++t]=i;
  43. }
  44. for(i=1;i<n;i++) sum+=(long long)(i-ls[i])*(rs[i]-i)*h[i];
  45. }
  46. int main()
  47. {
  48. scanf("%s%s",s1,s2);
  49. len1=strlen(s1),len2=strlen(s2);
  50. int i;
  51. for(i=0;i<len1;i++) r[i]=s1[i]-'a'+2;
  52. r[len1]=0,n=len1+1,m=27;
  53. work(),ans-=sum;
  54. for(i=0;i<len2;i++) r[i+len1+1]=s2[i]-'a'+2;
  55. r[len1+len2+1]=1;
  56. n=len1+len2+2,m=28;
  57. work(),ans+=sum;
  58. for(i=0;i<len2;i++) r[i]=s2[i]-'a'+2;
  59. r[len2]=0,n=len2+1,m=27;
  60. work(),ans-=sum;
  61. printf("%lld",ans);
  62. return 0;
  63. }

【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈的更多相关文章

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

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

  2. BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)

    题目链接 给定两个字符串,求它们有多少个相同子串.相同串的位置不同算多个. POJ3145简化版. 后缀自动机做法见这儿,又快又好写(一下就看出差距了..) //13712kb 4076ms #inc ...

  3. [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1212  Solved: 694[Submit][Stat ...

  4. BZOJ4566: [Haoi2016]找相同字符(后缀自动机)

    题意 题目链接 Sol 直接在SAM上乱搞 枚举前缀,用SAM统计可以匹配的后缀,具体在匹配的时候维护和当前节点能匹配的最大值 然后再把parent树上的点的贡献也统计上,这部分可以爆跳parent树 ...

  5. BZOJ4566 [Haoi2016]找相同字符【SAM】

    BZOJ4566 [Haoi2016]找相同字符 给定两个字符串\(s和t\),要求找出两个字符串中所有可以相互匹配的子串对的数量 首先考虑可以怎么做,我们可以枚举\(t\)串的前缀\(t'\),然后 ...

  6. 【BZOJ-3238】差异 后缀数组 + 单调栈

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

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

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

  8. BZOJ_3879_SvT_后缀数组+单调栈

    BZOJ_3879_SvT_后缀数组+单调栈 Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个 ...

  9. BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)

    BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...

随机推荐

  1. android的五大布局(layout)

    Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建 筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLa ...

  2. django如何修改开发服务器的端口

    我们启动django开发服务器,输入命令 manage.py  runserver  默认的端口是8000. 我们在浏览器中输入127.0.0.1:8000,可以访问8000端口 我们先停掉djang ...

  3. SSH整合简单例子

    说明:简单SSH整合,struts版本2.3.32,spring版本3.2.9,hibernate版本3.6.10 一.开发步骤 1 引jar包,创建用户library.使用的包和之前博文相同,可以参 ...

  4. vivado sdk生成elf文件出错:make: Interrupt/Exception caught (code = 0xc00000fd, addr = 0x4227d3)

    vivado sdk生成elf文件出错:make: Interrupt/Exception caught (code = 0xc00000fd, addr = 0x4227d3) Might be a ...

  5. nginx 查看访问 IP 并封禁 IP 详解

    1.查找服务器所有访问者ip方法: awk '{print $1}' nginx_access.log |sort |uniq -c|sort -n nginx.access.log 为nginx访问 ...

  6. nginx vhosts rewrite 独立文件的方式出现

    [root@web01 /]# cat /app/server/nginx/conf/nginx.conf user www www; worker_processes ; error_log /ap ...

  7. MySQL主从同步那点事儿

    一.前言 关于mysql主从同步,相信大家都不陌生,随着系统应用访问量逐渐增大,单台数据库读写访问压力也随之增大,当读写访问达到一定瓶颈时,将数据库的读写效率骤然下降,甚至不可用;为了解决此类问题,通 ...

  8. 分页技术框架(Pager-taglib)学习一(页面分页)

    一.Pager-taglib简介     1.Pager-taglib,支持多种风格的分页显示.实际上她是一个Jsp标签库,为在JSP上显示分页信息而设计的一套标签,通过这些标签的不同的组合,会形成多 ...

  9. eclipse中使用weblogic作为服务器控制台中文乱码

    使用WebLogic时控制台输出中文乱码解决方法:   1.找到weblogic安装目录,当前项目配置的domain   2.找到bin下的setDomainEnv.cmd文件   3.打开文件,从文 ...

  10. sitemesh 学习之 meta 引入

    在上篇笔记学习了sitemesh的基本用法,这里还有另一种用法 在sitemesh.jar有一个默认的sitemesh-default文件 ,这个文件是可以指定的 可以指定的文件名的sitemesh. ...