http://172.20.6.3/Problem_Show.asp?id=1547

http://www.lydsy.com/JudgeOnline/problem.php?id=4566

单纯后缀数组是O(n^2)应该是40分

似乎后缀自动机是正解。

但是后缀数组+并查集也可以乱搞a掉,这里写的是并查集写法,也算是get了一个并查集的用法,某种意义上并查集可以用来维护区间最大值最小值的贡献,实现方法见代码。

定义字符串大小的整型变量时候,

char siz;

导致re什么的,

我大概是个zz。

顺便存个板子,抄紫萱学姐的板子。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. using namespace std;
  7. const int maxn=;
  8. const int pl=;
  9. int sa[maxn*+pl]={};//排名第i的是从sa[i]开始的数组
  10. int rk[maxn*+pl]={};//i的排名
  11. int height[maxn*+pl]={};//排名第i的与排名第i-1的最长相同前缀长度
  12. int temp[maxn*+pl]={};//暂时的排名
  13. int cnt[maxn*+pl]={};//第i种(字典序)前缀的有多少个(的前缀和)
  14. int p[maxn*+pl]={};//临时对这一次需要用的sa的储存,处理了后缀长度不同的情况。
  15. char ch[maxn*+pl]={},ch1[maxn]={},ch2[maxn]={};
  16. int siz1,siz2,siz;
  17. int fa[maxn*+pl]={},a[maxn*+pl]={},lef[maxn*+pl]={},rig[maxn*+pl]={};
  18. inline bool equ(int x,int y,int l){return rk[x]==rk[y]&&rk[x+l]==rk[y+l];}
  19. void SA(){
  20. for(int i=;i<=siz;i++)rk[i]=ch[i],sa[i]=i;
  21. for(int i,sig=,l=,pos=;pos<siz;sig=pos){//l从0开始是预处理
  22. pos=;
  23. for(i=siz-l+;i<=siz;i++)p[++pos]=i;
  24. for(i=;i<=siz;i++)if(sa[i]>l)p[++pos]=sa[i]-l;
  25. for(i=;i<=sig;i++)cnt[i]=;
  26. for(i=;i<=siz;i++)cnt[rk[p[i]]]++;
  27. for(i=;i<=sig;i++)cnt[i]+=cnt[i-];
  28. for(i=siz;i>;i--){sa[cnt[rk[p[i]]]]=p[i];cnt[rk[p[i]]]--;}
  29. pos=;
  30. for(i=;i<=siz;i++){
  31. if(equ(sa[i],sa[i-],l))temp[sa[i]]=pos ;
  32. else temp[sa[i]]=++pos;
  33. }for(i=;i<=siz;i++)rk[i]=temp[i];
  34. if(l==)l=;
  35. else l<<=;
  36. }
  37. for(int i=,k=;i<=siz;i++){
  38. /*对于每一个位置的后缀,下一个位置的后缀可匹配的最短长度
  39. 一定大于等于该位置可匹配的长度-1,显然。所以是O(n)的算法
  40. */
  41. if(rk[i]==){k=;continue;}
  42. if(k>)k--;
  43. int j=sa[rk[i]-];
  44. while(ch[i+k]==ch[j+k])k++;
  45. height[rk[i]]=k;
  46. }
  47. }
  48. bool mcmp(int x,int y){return height[x]>height[y];}
  49. int getfa(int x){
  50. if(x!=fa[x])fa[x]=getfa(fa[x]);
  51. return fa[x];
  52. }
  53. int main(){
  54. //freopen("a.in","r",stdin);
  55. scanf("%s",&ch1);siz1=strlen(ch1);
  56. scanf("%s",&ch2);siz2=strlen(ch2);
  57. ch[siz1+]='z'+;siz=siz1+siz2+;
  58. for(int i=;i<siz1;i++)ch[i+]=ch1[i];
  59. for(int i=;i<siz2;i++)ch[siz1++i]=ch2[i];
  60. SA();
  61. for(int i=;i<=siz;i++){
  62. a[i]=fa[i]=i;
  63. lef[i]=(sa[i]<=siz1);
  64. rig[i]=^lef[i];
  65. }sort(a+,a++siz,mcmp);
  66. long long ans=;
  67. int x,y;
  68. for(int i=;i<=siz;i++){
  69. if(a[i]==)continue;
  70. x=getfa(a[i]);y=getfa(a[i]-);
  71. ans+=(long long)height[a[i]]*(long long)(lef[x]*rig[y]+rig[x]*lef[y]);
  72. lef[x]+=lef[y];rig[x]+=rig[y];fa[y]=x;
  73. }printf("%lld\n",ans);
  74. return ;
  75. }

更新:http://www.cnblogs.com/137shoebills/p/8511439.html 这是一道板子题的代码,注释应该被我完善了,更加清晰一点,所以我为什么要先写一道组合题再写板子啊喂。

BZOJ 4566 JZYZOJ 1547 [haoi2016T5]找相同子串 后缀数组 并查集的更多相关文章

  1. BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )

    求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N)) ------------------------- ...

  2. BZOJ 4199 [Noi2015]品酒大会:后缀数组 + 并查集

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4199 题意: 给你一个长度为n的字符串s,和一个长为n的数组v. 对于每个整数r∈[0,n ...

  3. URAL 1297 最长回文子串(后缀数组)

    1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB The “U.S. Robots” HQ has just received a ...

  4. poj 2774 最长公共子串 后缀数组

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 25752   Accepted: 10 ...

  5. poj 1743 Musical Theme(最长重复子串 后缀数组)

    poj 1743 Musical Theme(最长重复子串 后缀数组) 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复 ...

  6. BZOJ 3230 相似子串 | 后缀数组 二分 ST表

    BZOJ 3230 相似子串 题面 题解 首先我们要知道询问的两个子串的位置. 先正常跑一遍后缀数组并求出height数组. 对于每一个后缀suffix(i),考虑以i开头的子串有多少是之前没有出现过 ...

  7. bzoj 3230 相似子串——后缀数组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3230 作出后缀数组,从 LCP 看每个位置对于本质不同子串的贡献,而且他们已经按前面部分排好 ...

  8. BZOJ 1396: 识别子串( 后缀数组 + 线段树 )

    这道题各位大神好像都是用后缀自动机做的?.....蒟蒻就秀秀智商写一写后缀数组解法..... 求出Height数组后, 我们枚举每一位当做子串的开头. 如上图(x, y是height值), Heigh ...

  9. BZOJ 3230: 相似子串(后缀数组)

    传送门 解题思路 其实题目挺好想的.首先子串排名可以由后缀数组求得,因为不算重复的,所以后缀数组的每个后缀排名的去掉\(lcp\)的前缀排名为当前后缀的子串排名.这样就可以预处理出每个后缀的\(l,r ...

随机推荐

  1. JavaScript数据类型和转换

    JavaScript数据类型 1.Boolean(布尔) 布尔:(值类型)var b1=true;//布尔类型 2.Number(数字) 数值:(值类型)var n1=3.1415926;//数值类型 ...

  2. MSSQL 基础知识002

    ---启用sa账号 1. 先使用一个windows账号登陆. 2.在数据库实例上面右键,属性,安全性,登录名,sa. 右键,属性. 常规,修改sa的密码. 状态,启用sa账号. 主键的作用: 1.唯一 ...

  3. docker ubuntu容器更换阿里源(转)

    问题:使用docker 利用下载的ubuntu镜像启动容器时,使用的源下载更新软件的速度较慢. 解决这个问题的方法是跟新ubuntu容器的源 示例:以ubuntu为基础镜像 启动一个名称为 test0 ...

  4. 16级第二周寒假作业E题

    Home_W的位运算4 TimeLimit:2000MS  MemoryLimit:128MB 64-bit integer IO format:%I64d Problem Description 给 ...

  5. 14 - 函数参数检测-inspect模块

    目录 1 python类型注解 2 函数定义的弊端 3 函数文档 4 函数注解 4.1 annotation属性 5 inspect模块 5.1 常用方法 5.2 signature类 5.3 par ...

  6. ELK&ElasticSearch5.1基础概念及配置文件详解【转】

    1. 配置文件 elasticsearch/elasticsearch.yml 主配置文件 elasticsearch/jvm.options jvm参数配置文件 elasticsearch/log4 ...

  7. WebHeaderCollection类

    .net添加http报头 string[] allKeys = WebHeaderCollection.AllKeys; for (int i = 0; i < allKeys.Length; ...

  8. 安装 Xamarin for Visual Studio

    总得来说,Xamarin 有“联网自动安装”和“手动安装”两种方式. 说明:本文涉及得资源链接都是官网的,同时,在 我的网盘 也有相关备份. 现在,我就以 Windows 为例来大概说明……(-=-我 ...

  9. git版本控制系统常见操作总结

    简介 Git是强大的版本控制系统,主要功能是针对代码.配置文件等文本进行版本控制.备份等,同时个人认为还是分发代码的一个不错的方式. 常见用法 #创建远程git仓库 [root@test88 ~]# ...

  10. redis常见数据操作

    redis中有5种常见的数据类型,针对这5种数据类型有着相应的数据操作. 1.String(键值对为String - String) set k1 v1 get k1 getset k1 v1 - h ...