题意

考虑将\(s1\)和\(s2\)接在一起求出相同子串个数,再求出\(s1\)自己匹配的相同子串个数和\(s2\)自己匹配的相同子串个数减去即可。

如何求相同子串个数:

我们知道子串的集合即所有后缀的前缀集合,于是实际上答案就是:

\(\sum\limits_{i=1}^n\sum\limits_{j=i+1}^nlcp(sa_i,sa_j)\)

接下来就和这题相同了。

code:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int maxn=400010;
  5. int n,m,num,top;
  6. int sa[maxn],rk[maxn],oldrk[maxn],id[maxn],tmpid[maxn],cnt[maxn],height[maxn],L[maxn],R[maxn],sta[maxn];
  7. ll ans;
  8. char s1[maxn],s2[maxn],s[maxn];
  9. inline bool check(int x,int y,int k){return oldrk[x]==oldrk[y]&&oldrk[x+k]==oldrk[y+k];}
  10. inline void get_sa(char* s,int len)
  11. {
  12. memset(cnt,0,sizeof(cnt));
  13. num=300;
  14. for(int i=1;i<=len;i++)cnt[rk[i]=s[i]]++;
  15. for(int i=1;i<=num;i++)cnt[i]+=cnt[i-1];
  16. for(int i=len;i;i--)sa[cnt[rk[i]]--]=i;
  17. for(int t=1;t<=len;t<<=1)
  18. {
  19. int tot=0;
  20. for(int i=len-t+1;i<=len;i++)id[++tot]=i;
  21. for(int i=1;i<=len;i++)if(sa[i]>t)id[++tot]=sa[i]-t;
  22. tot=0;
  23. memset(cnt,0,sizeof(cnt));
  24. for(int i=1;i<=len;i++)cnt[tmpid[i]=rk[id[i]]]++;
  25. for(int i=1;i<=num;i++)cnt[i]+=cnt[i-1];
  26. for(int i=len;i;i--)sa[cnt[tmpid[i]]--]=id[i];
  27. memcpy(oldrk,rk,sizeof(rk));
  28. for(int i=1;i<=len;i++)rk[sa[i]]=check(sa[i-1],sa[i],t)?tot:++tot;
  29. num=tot;
  30. if(num==len)break;
  31. }
  32. for(int i=1,j=0;i<=len;i++)
  33. {
  34. if(j)j--;
  35. while(s[i+j]==s[sa[rk[i]-1]+j])j++;
  36. height[rk[i]]=j;
  37. }
  38. }
  39. inline ll calc(int len)
  40. {
  41. ll res=0;
  42. sta[top=1]=1;
  43. for(int i=2;i<=len;i++)
  44. {
  45. while(top&&height[sta[top]]>=height[i])R[sta[top--]]=i;
  46. L[i]=sta[top];sta[++top]=i;
  47. }
  48. while(top)R[sta[top--]]=len+1;
  49. for(int i=2;i<=len;i++)res+=1ll*height[i]*(R[i]-i)*(i-L[i]);
  50. return res;
  51. }
  52. int main()
  53. {
  54. scanf("%s%s",s1+1,s2+1);
  55. n=strlen(s1+1),m=strlen(s2+1);
  56. get_sa(s1,n);ans-=calc(n);
  57. get_sa(s2,m);ans-=calc(m);
  58. for(int i=1;i<=n;i++)s[i]=s1[i];
  59. s[n+1]='#';
  60. for(int i=1;i<=m;i++)s[n+i+1]=s2[i];
  61. get_sa(s,n+m+1);ans+=calc(n+m+1);
  62. printf("%lld\n",ans);
  63. return 0;
  64. }

luoguP3181 [HAOI2016]找相同字符的更多相关文章

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

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

  2. bzoj4566 / P3181 [HAOI2016]找相同字符

    P3181 [HAOI2016]找相同字符 后缀自动机 (正解应是广义后缀自动机) 并不会广义后缀自动机. 然鹅可以用普通的后缀自动机.   我们先引入一个问题:算出从一个串内取任意两个不重合子串完全 ...

  3. 【BZOJ4566】[HAOI2016]找相同字符

    [BZOJ4566][HAOI2016]找相同字符 题面 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 其中\(1\le ...

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

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

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

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

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

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

  7. [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)

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

  8. BZOJ_4566_[Haoi2016]找相同字符_后缀自动机

    BZOJ_4566_[Haoi2016]找相同字符_后缀自动机 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有 ...

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

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

随机推荐

  1. 《深度访谈:华为开源数据格式 CarbonData 项目,实现大数据即席查询秒级响应》

    深度访谈:华为开源数据格式 CarbonData 项目,实现大数据即席查询秒级响应   Tina 阅读数:146012016 年 7 月 13 日 19:00   华为宣布开源了 CarbonData ...

  2. Windows10 下利用Hyper-V安装CentOS系统

    开启Windows10的Hyper-v功能(需要重启电脑) 控制面板→程序→启用或关闭Windows功能→打开Hyper-v→确定 创建虚拟机 在Windows管理工具中找到Hyper-v管理器并双击 ...

  3. shell基础概念, if+命令, shell中引用python, shell脚本的几种执行方式

    说明: 虚拟机中shell_test目录用来练习shell, 其中有个test.log文件用来存放日志 #!/usr/bin/bash      # shell文件开头, 用来指定该文件使用哪个解释器 ...

  4. Codeforces Round #594 (Div. 1)

    Preface 这场CF真是细节多的爆炸,B,C,F都是大细节题,每道题都写了好久的说 CSP前的打的最后一场比赛了吧,瞬间凉意满满 希望CSP可以狗住冬令营啊(再狗不住真没了) A. Ivan th ...

  5. Python进阶实战之三级菜单

    目录 一.Python进阶实战之三级菜单 1.1 面条版 1.2 文艺青年版 一.Python进阶实战之三级菜单 打印省.市.县三级菜单 可返回上一级 可随时退出程序 1.1 面条版 menu = { ...

  6. SQLite安装及使用教程

    SQLite是一款轻型的嵌入式关系数据库,轻量级,效率高,操作起来也特别方便 我们今天来讲解一下SQLite的安装和一些基本操作 SQLite下载 如果是64位机,下载下面的两个解压就好 在dos界面 ...

  7. pytest框架之fixture前置和后置

    一.conftest.py 定义公共的fixture,多个测试类中都可以调用 pytest提供了conftest.py文件,可以将fixture定义在此文件中 运行测试用例时,不需要去导入这个文件,会 ...

  8. node环境下多种方式“get数据解析”

    1.自己写 const http = require('http'); http.createServer(function(req,res){ var get = {}; if(req.url.in ...

  9. (四)初识NumPy(函数和图像的数组表示)

    本章节主要介绍NumPy中的三个主要的函数,分别是随机函数.统计函数和梯度函数,以及一个较经典的用数组来表示图像的栗子!,希望大家能有新的收货,共同进步! 一.np.random的随机函数(1) ra ...

  10. IDA+Windbg IDA+OD 连动调试插件

    https://github.com/bootleg/ret-sync 使用注意事项:多次测试,最好现在IDA中启动,然后再在OD或WINDBG(.load sync)中启动. 这个工具还是相当给力的 ...