被虐爆了 cry 我的hash是真的菜啊。。。

poj3349 肝了一个上午心态崩了。。。一上午fail了42次我的天,一开始搞了个排序复杂度多了个log,而且是那种可能不同值相等的hash,把12种情况枚举,TLE了,然后就用了那种栈循环的hash,又T又W,期间大力搞大质数想要各个不同的雪花hash值不同,然后改成链表,最后一怒之下把最小表示法删了换暴力就A了。。想了想是因为我以为它的角度不会重复然后就偷了一波懒。。。这道题告诉我,假如重复还是得管的。。。hash应该作为一个筛选的工具。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL; int next[],last[];
int len,hash[][],key[];
int c[];
bool check(int k)
{
for(int i=;i<=;i++)
{
bool bk=true;
for(int j=;j<=;j++)
if(hash[k][j]!=c[(i+j-)%+]){bk=false;break;}
if(bk==true)return true;
}
for(int i=;i<=;i++)
{
bool bk=true;
for(int j=;j<=;j++)
if(hash[k][j]!=c[(i+(-j+)-)%+]){bk=false;break;}
if(bk==true)return true;
}
return false;
}
bool calc()
{
int d=;
for(int i=;i<=;i++)d+=c[i];
int x=d%;
for(int k=last[x];k;k=next[k])
if(key[k]==d&&check(k)==true)return true; key[++len]=d;
for(int i=;i<=;i++)hash[len][i]=c[i];
next[len]=last[x];
last[x]=len;
return false;
}
int main()
{
int n;
scanf("%d",&n);len=;memset(last,,sizeof(last));
memset(key,,sizeof(key));
for(int i=;i<=n;i++)
{
for(int j=;j<=;j++)scanf("%d",&c[j]);
if(calc()==true){printf("Twin snowflakes found.\n");return ;}
}
printf("No two snowflakes are alike.\n");
return ;
}

poj3349

兔子与兔子 这个还是简单一点的,加深了对于mod之后的运算的满足的理解吧。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int s[],Bin[];
char ss[];
int main()
{
scanf("%s",ss+);int len=strlen(ss+);
s[]=;Bin[]=;
for(int i=;i<=len;i++)
Bin[i]=Bin[i-]*, s[i]=s[i-]+Bin[i]*(ss[i]-'a'); int Q,l,r;
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&l,&r);
int d1=(s[r]-s[l-])*Bin[len-r];
scanf("%d%d",&l,&r);
int d2=(s[r]-s[l-])*Bin[len-r];
if(d1==d2)printf("Yes\n");
else printf("No\n");
}
return ;
}

兔子和兔子

poj3974 马拉车原问题多个log的hash做法。。就是对于每个点二分回文的长度,然后判断是否匹配

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int len;
int Bin[],zh[],fh[];
bool check(int i,int mid)
{
int l1=i-mid+,r1=i;
int l2=i,r2=i+mid-; int d1=(zh[r1]-zh[l1-])*Bin[len-r1];
int d2=(fh[l2]-fh[r2+])*Bin[l2-]; return d1==d2;
}
bool check2(int i,int mid)
{
int l1=i-mid+,r1=i;
int l2=i+,r2=(i+)+mid-; int d1=(zh[r1]-zh[l1-])*Bin[len-r1];
int d2=(fh[l2]-fh[r2+])*Bin[l2-]; return d1==d2;
} char ss[];
int main()
{
int T_T=;
while(scanf("%s",ss+)!=EOF)
{
len=strlen(ss+);
if(ss[]=='E'&&ss[]=='N'&&ss[]=='D'&&len==)break;
printf("Case %d: ",++T_T); Bin[]=;zh[]=;fh[len+]=;
for(int i=;i<=len;i++)
Bin[i]=Bin[i-]*, zh[i]=zh[i-]+Bin[i]*(ss[i]-'a'+);
for(int i=len;i>=;i--)
fh[i]=fh[i+]+Bin[len-i+]*(ss[i]-'a'+); int mmax=;
for(int i=;i<=len;i++)
{
int l=,r=min(i,len-i+),ans=;
while(l<=r)
{
int mid=(l+r)/;
if(check(i,mid)==true)
{
ans=mid;
l=mid+;
}
else r=mid-;
}
mmax=max(mmax,ans*-);
if(i!=len)
{
l=,r=min(i,len-(i+)+),ans=;
while(l<=r)
{
int mid=(l+r)/;
if(check2(i,mid)==true)
{
ans=mid;
l=mid+;
}
else r=mid-;
}
mmax=max(mmax,ans*);
}
}
printf("%d\n",mmax);
}
return ;
}

poj3974

后缀数组 后缀数组原问题多个log的hash做法,做到这题感觉hash写得很顺啊,调都没调就过了,具体做法是这样的,对于sa,我归并排序下标(其实就是对应后缀),然后用二分+hash搞出要比较大小的后缀的前缀,比较它们前缀的后一位就知道那个后缀较小了。height同理二分+hash可得

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int len;char ss[];
int ha[],Bin[];
bool check(int l1,int l2,int L)
{
int r1=l1+L-,r2=l2+L-; int d1=(ha[r1]-ha[l1-])*Bin[len-r1];
int d2=(ha[r2]-ha[l2-])*Bin[len-r2]; return d1==d2;
}
bool bijiao(int x,int y)
{
int l=,r=len-max(x,y)+,ans=;
while(l<=r)
{
int mid=(l+r)/;
if(check(x,y,mid)==true)
{
ans=mid;
l=mid+;
}
else r=mid-;
}
return ss[x+ans]<ss[y+ans];
}
int id[],tt[];
void mergesort(int l,int r)
{
if(l==r)return ;
int mid=(l+r)/;
mergesort(l,mid);mergesort(mid+,r); int i=l,j=mid+,p=l;
while(i<=mid&&j<=r)
{
if(bijiao(id[i],id[j])==true)
tt[p++]=id[i++];
else
tt[p++]=id[j++];
}
while(i<=mid)tt[p++]=id[i++];
while(j<=r) tt[p++]=id[j++]; for(int i=l;i<=r;i++)id[i]=tt[i];
} int main()
{
scanf("%s",ss+),len=strlen(ss+);
Bin[]=;
for(int i=;i<=len;i++)
Bin[i]=Bin[i-]*, ha[i]=ha[i-]+Bin[i]*(ss[i]-'a'+); for(int i=;i<=len;i++)id[i]=i;
mergesort(,len);
for(int i=;i<len;i++)printf("%d ",id[i]-);
printf("%d\n",id[len]-); printf("");
for(int i=;i<=len;i++)
{
int l=,r=len-max(id[i-],id[i])+,ans=;
while(l<=r)
{
int mid=(l+r)/;
if(check(id[i-],id[i],mid)==true)
{
ans=mid;
l=mid+;
}
else r=mid-;
}
printf(" %d",ans);
}
printf("\n");
return ;
}

后缀数组

总结一下,hash的用途在判定相等而不支持大小比较,好像很适配于二分把问题转成判定性问题以后?

补基础的伪老年选手yzh好菜啊,一天才一章。。

0x14 hash的更多相关文章

  1. 算法竞赛进阶指南0x14 Hash

    组成部分: 哈希函数: 链表 AcWing137. 雪花雪花雪花 因为所需要数据量过于大,所以只能以O(n)的复杂度. 所以不可能在实现的过程中一一顺时针逆时针进行比较,所以采用一种合适的数据结构. ...

  2. PHP数组/Hash表的实现/操作、PHP变量内核实现、PHP常量内核实现 - [ PHP内核学习 ]

    catalogue . PHP Hash表 . PHP数组定义 . PHP变量实现 . PHP常量实现 1. PHP Hash表 0x1: 基本概念 哈希表在实践中使用的非常广泛,例如编译器通常会维护 ...

  3. 通过PowerShell获取Windows系统密码Hash

    当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大 ...

  4. hash算法搜索获得api函数地址的实现,"kernel32.dll", "CreateThread"

    我们一般要获得一个函数的地址,通常采用的是明文,例如定义一个api函数字符串"MessageBoxA",然后在GetProcAddress函数中一个字节一个字节进行比较.这样弊端很 ...

  5. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  6. 对抗密码破解 —— Web 前端慢 Hash

    (更新:https://www.cnblogs.com/index-html/p/frontend_kdf.html ) 0x00 前言 天下武功,唯快不破.但在密码学中则不同.算法越快,越容易破. ...

  7. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  8. hash表长度优化证明

    hash表冲突的解决方法一般有两个方向: 一个是倾向于空间换时间,使用向量加链表可以最大程度的在节省空间的前提下解决冲突. 另外一个倾向于时间换空间,下面是关于这种思路的一种合适表长度的证明过程: 这 ...

  9. SQL Server-聚焦查询计划Stream Aggregate VS Hash Match Aggregate(二十)

    前言 之前系列中在查询计划中一直出现Stream Aggregate,当时也只是做了基本了解,对于查询计划中出现的操作,我们都需要去详细研究下,只有这样才能对查询计划执行的每一步操作都了如指掌,所以才 ...

随机推荐

  1. 关于一些UI的插件(杂)

    1.时间插件 //日期框 $('.date-picker').datepicker(); 2.checkbox 保存checkbox的值 // 组装选择的标签 var check = $(" ...

  2. linux install PyMsql

    # 安装pip curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python get-pip.py # 安装PyMysql pip in ...

  3. 【Arduino】基于arduino的激光坦克

    历经了总共40来个小时,终于将这个激光坦克做好了. 这是本人的第一件像样的arduino作品. 用arduino为主控制器,配有32路舵机驱动板(在这有些大材小用了),以及一个wr703n的路由器当做 ...

  4. Windows 10 常用软件推荐

    QQ/TIM 大众的通讯工具,十多年之后的今天,依然是国内常驻用户第一的通讯工具 截图.远程桌面.视频会议.文件传送依旧是非常好用 TIM 算是轻聊版的升级版 微信 for Windows 近年新兴的 ...

  5. 网页小技巧-360doc个人图书馆复制文字

    用过这个网站的人知道,当你像平时一样复制网页的地址时,这个网站会弹出如下的提示框: 这时候如果你没有账号,又不想注册.真的是一种很崩溃的感觉,但是除了注册登录外,就没有其他的办法了吗? 熟悉网页调试的 ...

  6. jQuery添加新的元素

    append() - 在被选元素的结尾插入内容 prepend() - 在被选元素的开头插入内容 after() - 在被选元素之后插入内容 before() - 在被选元素之前插入内容 $(&quo ...

  7. Python笔记8----DataFrame(二维)

    目录: DataFrame概念 DataFrame创建 基本操作 查看.索引 修改.删除 统计功能 条件筛选 合并 去除空值 4. 一些常用的函数 apply memory_usage pivot_t ...

  8. 【Git教程】Git教程之分支管理

      在前一篇文章中,主要针对Git本地仓库和远程仓库的基本操作命令进行了简要介绍,本文主要集中介绍Git的另一个主要的特点:分支管理和多人协作. 什么是分支管理   当一个任务需要多人协作完成时,每个 ...

  9. [luogu P2590 ZJOI2008] 树的统计 (树链剖分)

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...

  10. P3375 【模板】KMP字符串匹配 (KMP模板)

    题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如果你不知道这是什么意思也不要问,去百度 ...