二分答案,然后搞出hash值扔到哈希表里。期望复杂度O(n*log(n))。

<法一>next数组版哈希表

#include<cstdio>
#include<cstring>
using namespace std;
typedef unsigned long long ull;
const ull seed=29;
#define MOD 2007
ull seeds[2001],ord[301],v[6][2000];
int n,ls[6],minv=2147483647,mini,first[6][MOD],next[6][2000],en[6];
char s[6][2001];
void AddEdge(const int &o,const int &U,const ull &V)
{v[o][en[o]]=V;next[o][en[o]]=first[o][U];first[o][U]=en[o]++;
}
ull BKDRhash(const char str[],const int &L,const int &R)
{ull res=0;for(int i=L;i<R;++i)res=res*seed+ord[str[i]];return res;
}
void init()
{for(int i='a',j=1;i<='z';++i,++j)ord[i]=(ull)j;seeds[0]=1;for(int i=1;i<=minv;++i)seeds[i]=seeds[i-1]*seed;
}
bool Find(const int &o,const ull &x)
{int y=(int)(x%MOD);for(int i=first[o][y];i!=-1;i=next[o][i]) if(v[o][i]==x) return 1;return 0;
}
bool Find_In_All(const ull &x)
{for(int i=1;i<=n;++i)if(i!=mini&&(!Find(i,x)))return 0;return 1;
}
bool check(const int &x)
{memset(first,-1,sizeof(first));memset(en,0,sizeof(en));for(int i=1;i<=n;++i) if(i!=mini){ull hs=BKDRhash(s[i],0,x);AddEdge(i,hs%MOD,hs);for(int j=x;j<ls[i];++j){hs=hs*seed+ord[s[i][j]];hs-=seeds[x]*ord[s[i][j-x]];AddEdge(i,hs%MOD,hs);}}ull hs=BKDRhash(s[mini],0,x);if(Find_In_All(hs)) return 1;for(int i=x;i<minv;++i){hs=hs*seed+ord[s[mini][i]];hs-=seeds[x]*ord[s[mini][i-x]];if(Find_In_All(hs)) return 1;}return 0;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%s",s[i]);ls[i]=strlen(s[i]);if(ls[i]<minv){minv=ls[i];mini=i;}}init();int l=0,r=minv+1;while(l<r){  int mid=l+r>>1;  if(check(mid)) l=mid+1;  else r=mid;}printf("%d\n",l-1);return 0;
}

<法二>vector版哈希表

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef unsigned long long ull;
const ull seed=29;
#define MOD 2007
typedef vector<ull>::iterator VER;
vector<ull>List[6][2007];
ull seeds[2001],ord[301];
int n,ls[6],minv=2147483647,mini;
char s[6][2001];
ull BKDRhash(const char str[],const int &L,const int &R)
{ull res=0;for(int i=L;i<R;++i)res=res*seed+ord[str[i]];return res;
}
void init()
{for(int i='a',j=1;i<='z';++i,++j)ord[i]=(ull)j;seeds[0]=1;for(int i=1;i<=minv;++i)seeds[i]=seeds[i-1]*seed;
}
bool Find(const int &o,const ull &x)
{int y=(int)(x%MOD);for(VER it=List[o][y].begin();it!=List[o][y].end();++it)if(*it==x)return 1;return 0;
}
bool Find_In_All(const ull &x)
{for(int i=1;i<=n;++i)if(i!=mini&&(!Find(i,x)))return 0;return 1;
}
bool check(const int &x)
{for(int i=1;i<=n;++i) if(i!=mini){ull hs=BKDRhash(s[i],0,x);List[i][hs%MOD].push_back(hs);for(int j=x;j<ls[i];++j){hs=hs*seed+ord[s[i][j]];hs-=seeds[x]*ord[s[i][j-x]];List[i][hs%MOD].push_back(hs);}}ull hs=BKDRhash(s[mini],0,x);if(Find_In_All(hs)) return 1;for(int i=x;i<minv;++i){hs=hs*seed+ord[s[mini][i]];hs-=seeds[x]*ord[s[mini][i-x]];if(Find_In_All(hs)) return 1;}return 0;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%s",s[i]);ls[i]=strlen(s[i]);if(ls[i]<minv){minv=ls[i];mini=i;}}init();int l=0,r=minv+1;while(l<r){  int mid=l+r>>1;  if(check(mid)) l=mid+1;  else r=mid;}printf("%d\n",l-1);return 0;
}

转载于:https://www.cnblogs.com/autsky-jadek/p/4245097.html

【二分答案】【哈希表】【字符串哈希】bzoj2946 [Poi2000]公共串相关推荐

  1. ds哈希查找—二次探测再散列_大白话之哈希表和哈希算法

    哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...

  2. 大白话之哈希表和哈希算法

    哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...

  3. 【哈希】关于哈希表和哈希函数的理解与应用

    0.概述 哈希,或者说散列,在教科书上写的都比较详细,通常包括的内容有散列的方法,散列冲突的解决等.本文暂且不表这些基础知识,更多的重点在于哈希的一些应用和题目,对于哈希表.哈希函数从来没有学习过或者 ...

  4. 高级数据结构与算法 | 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶

    文章目录 哈希 哈希函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列的解决方法 开散列的解决方法 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) 插入 查找 删除 完整 ...

  5. 哈希表及哈希冲突解决办法

    哈希表及哈希冲突解决办法 目录 什么是哈希表? 哈希表的数据结构 哈希冲突 哈希冲突解决办法 1. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直 ...

  6. 哈希表添加哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。typedef enum{ HASH_OK, -icoding

    哈希表添加 哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加 ...

  7. 【数据结构】哈希表、哈希值计算分析

    哈希表.哈希值计算分析 哈希表完整代码 引出哈希表 哈希表(Hash Table) 哈希冲突(Hash Collision) JDK1.8的哈希冲突解决方案 哈希函数 如何生成 key 的哈希值 In ...

  8. LeetCode哈希表(哈希集合,哈希映射)

    文章目录 哈希表 1.原理 2.复杂度分析 题目&推荐列表 哈希集合的应用 0.常用解题模板 1.lc217 存在重复元素 2.lc136 只出现一次的数字 3.快乐数 哈希映射的应用 0.常 ...

  9. 14 哈希表和哈希桶

    文章目录 一.哈希表 二.哈希函数 2.1. 直接定址法(常用) 2.2. 除留余数法(常用) 2.3. 几种不常用的方法 三.哈希冲突 四.闭散列 4.1. 线性探测 4.2. 负载因子 4.3. ...

最新文章

  1. oracle+块头csc,数据块转储及RDBA的转换
  2. WebSocket实战之————Workerman服务器的安装启动
  3. Thinkphp动态切换主题
  4. python怎么学最快-零基础怎么样才能学好Python?Python入门必看
  5. Linux grep命令——文本搜索工具
  6. HtmlUnit解析动态网页并采集网页列表到Excel
  7. 把2018年所有踩过的坑都记在这里。
  8. boost::intrusive::stateful_value_traits用法的测试程序
  9. java 制作小游戏_如何用java制作小游戏
  10. C# 8 新增小功能
  11. elementui Cascader 省市区联动选择器,应用与回显
  12. MS CRM 2011汇总更新5发布
  13. 百度云OCR文字识别
  14. Java项目:在线bbs论坛系统(java+SSM+JSP+bootstrap+jQuery+mysql)
  15. 垃圾邮件分类-朴素贝叶斯算法
  16. springboot 自定义注解拦截器
  17. 关于瓦力机器人的设计构想
  18. Android开发-基础入门
  19. 震惊科学界!DeepMind AI破解「蛋白质折叠」难题
  20. 【金猿人物展】红杉中国合伙人车品觉: 数字化转型的关键,源于数据战略

热门文章

  1. python 每日温度
  2. vs账号状态异常_西甲第35轮直播:皇家马德里vs阿拉维斯 皇马气势汹汹欲冲连胜势头!...
  3. linux ls统计文件个数
  4. 主题图标_Avada主题网站favicon图标设置详细图文教程
  5. java 原生数据类型的转换_Java基本数据类型转换分析
  6. c语言中常见的变量,C语言中的变量详解
  7. Java第三大的数,Java通过排序找出数组第三大数字
  8. 描述符:property 迭代器
  9. 2、UNIX、Linux操作系统的发展历程、介绍、应用领域
  10. Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析