【二分答案】【哈希表】【字符串哈希】bzoj2946 [Poi2000]公共串
二分答案,然后搞出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]公共串相关推荐
- ds哈希查找—二次探测再散列_大白话之哈希表和哈希算法
哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...
- 大白话之哈希表和哈希算法
哈希表概念 哈希表(散列表),是基于关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数(哈希函数 ...
- 【哈希】关于哈希表和哈希函数的理解与应用
0.概述 哈希,或者说散列,在教科书上写的都比较详细,通常包括的内容有散列的方法,散列冲突的解决等.本文暂且不表这些基础知识,更多的重点在于哈希的一些应用和题目,对于哈希表.哈希函数从来没有学习过或者 ...
- 高级数据结构与算法 | 哈希 :哈希冲突、负载因子、哈希函数、哈希表、哈希桶
文章目录 哈希 哈希函数 常见的哈希函数 字符串哈希函数 哈希冲突 闭散列的解决方法 开散列的解决方法 负载因子以及增容 对于闭散列 对于开散列结构 具体实现 哈希表(闭散列) 插入 查找 删除 完整 ...
- 哈希表及哈希冲突解决办法
哈希表及哈希冲突解决办法 目录 什么是哈希表? 哈希表的数据结构 哈希冲突 哈希冲突解决办法 1. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直 ...
- 哈希表添加哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。typedef enum{ HASH_OK, -icoding
哈希表添加 哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加 ...
- 【数据结构】哈希表、哈希值计算分析
哈希表.哈希值计算分析 哈希表完整代码 引出哈希表 哈希表(Hash Table) 哈希冲突(Hash Collision) JDK1.8的哈希冲突解决方案 哈希函数 如何生成 key 的哈希值 In ...
- LeetCode哈希表(哈希集合,哈希映射)
文章目录 哈希表 1.原理 2.复杂度分析 题目&推荐列表 哈希集合的应用 0.常用解题模板 1.lc217 存在重复元素 2.lc136 只出现一次的数字 3.快乐数 哈希映射的应用 0.常 ...
- 14 哈希表和哈希桶
文章目录 一.哈希表 二.哈希函数 2.1. 直接定址法(常用) 2.2. 除留余数法(常用) 2.3. 几种不常用的方法 三.哈希冲突 四.闭散列 4.1. 线性探测 4.2. 负载因子 4.3. ...
最新文章
- oracle+块头csc,数据块转储及RDBA的转换
- WebSocket实战之————Workerman服务器的安装启动
- Thinkphp动态切换主题
- python怎么学最快-零基础怎么样才能学好Python?Python入门必看
- Linux grep命令——文本搜索工具
- HtmlUnit解析动态网页并采集网页列表到Excel
- 把2018年所有踩过的坑都记在这里。
- boost::intrusive::stateful_value_traits用法的测试程序
- java 制作小游戏_如何用java制作小游戏
- C# 8 新增小功能
- elementui Cascader 省市区联动选择器,应用与回显
- MS CRM 2011汇总更新5发布
- 百度云OCR文字识别
- Java项目:在线bbs论坛系统(java+SSM+JSP+bootstrap+jQuery+mysql)
- 垃圾邮件分类-朴素贝叶斯算法
- springboot 自定义注解拦截器
- 关于瓦力机器人的设计构想
- Android开发-基础入门
- 震惊科学界!DeepMind AI破解「蛋白质折叠」难题
- 【金猿人物展】红杉中国合伙人车品觉: 数字化转型的关键,源于数据战略
热门文章
- python 每日温度
- vs账号状态异常_西甲第35轮直播:皇家马德里vs阿拉维斯 皇马气势汹汹欲冲连胜势头!...
- linux ls统计文件个数
- 主题图标_Avada主题网站favicon图标设置详细图文教程
- java 原生数据类型的转换_Java基本数据类型转换分析
- c语言中常见的变量,C语言中的变量详解
- Java第三大的数,Java通过排序找出数组第三大数字
- 描述符:property 迭代器
- 2、UNIX、Linux操作系统的发展历程、介绍、应用领域
- Java 线程同步组件 CountDownLatch 与 CyclicBarrier 原理分析