2020牛客暑期多校训练营All with Pairs(Hash,前缀函数)

All with Pairs

题目描述

在这里插入图片描述

输入描述:

在这里插入图片描述

输出描述:

在这里插入图片描述

示例1

输入

3
ab
ba
aba

输出

29

说明

在这里插入图片描述

题目大意

给定n个字符串,求所有字符串前缀与后缀相等的个数与前后缀的长度的平方的和。如样例,匹配长度为1,2,3的分别有4,4,1个,所以答案为
4 *1 ^2 +4 *2 ^2 +1 *3 ^2=29

分析

许多dalao们看到这题就会想到用map把所有的后缀(前缀)映射进去,然后对于每个前缀(后缀),就可以直接查找下就可以了。但是,map是pair和set合用,这全搞在一起是很慢的,看到1e6的长度,就是TLE。所以要找一个更加高深的算法。

HASH

哈希是字符串题目中的bug方法,基本上能水过去,实在不行还能骗不少分。本题中可以把后缀(前缀)的哈希值求出,然后将前缀(后缀)的哈希值与之比较,就能比较快捷地求出匹配了。但是哈希的进制搞成多少好呢?一般我们都是取一个素数进制,冲突的概率比较小。然而,本题有1e6的长度,以233进制的哈希为例,搞不好就是2331e6,炸上天。因此需要一个mod。但是这个mod之后,它也有概率会冲突。这就是看运气了。有一下3种比较好的解决这个办法。(后文采取第二种)
1、用大素数取模,这种冲突产生的概率就十分小了。
2、用unsigned long long,直接省略超出部分,概率小且写代码方便。
3、双哈希,这种方式就是取两种进制,然后都取一个mod,如果这都能冲突,那真可以买彩票了,唯一不足就是有点烦,蒟蒻不太喜欢这种写法。

以下是图示,是哈希的原理,即为进制转换,转换成233进制之类的。第一位的数值是2330 *当前位,以此类推。
在这里插入图片描述
具体代码见下。

void puthash(string a){
   
    int len=a.size();
    ull sum=0,p=1;//用ull解决冲突
    for(int i=len-1;i>=0;i--){
   
        sum+=(a[i]-'a'+1)*p;
        p*=233;
        mp[sum]++;
    
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值