首页 > 其他分享 >双哈希_Birthday_Cake

双哈希_Birthday_Cake

时间:2022-09-06 13:11:27浏览次数:100  
标签:return num1 int ll 后缀 Birthday 哈希 Cake const

Birthday Cake

思路:找到每个串的公共前后缀,统计公共前后缀之间的字符串的hash值,并判断所给n个串中是否存在符合条件的串
eg:abbddab
对于该串,我们不难发现,公共前后缀是ab,公共前后缀之间的串是bdd,我们需要统计所有串中bdd出现的次数
注意,求得不是最长公共前后缀,而是所有的公共前后缀
细节问题:1、取模
         2、RE可能是因为tmp定义为string,每次对tmp赋值的时候,tmp串会进行依次刷新,会造成堆栈溢出
#include<bits/stdc++.h>
#define ll long long
#define mp make_pair
using namespace std;

const int N = 4e5 + 10;
const ll m1 = 1e9 + 7;
const ll m2 = 1e9 + 9;
const int mod1 = 233;
const int mod2 = 19;
string st[N];
char tmp[N];
ll n, ans;
ll num1[N], num2[N], hash1[N], hash2[N];
map<pair<ll,ll>, int> cnt;

//每个串,只需要考虑长度小于等于该串的长度的串
bool cmp(string st1, string st2){
    if(st1.size() < st2.size()) return true;
    return false;
}

void init(){
    num1[0] = num2[0] = 1;
    for(int i = 1; i < N - 1; i++){
        num1[i] = num1[i - 1] * mod1 % m1;
        num2[i] = num2[i - 1] * mod2 % m2;
    }
}

ll gethash1(int l, int r){
    if(l > r) return 0;
    return (hash1[r] - (hash1[l - 1] * num1[r - l + 1]) % m1 + m1)%m1;
}

ll gethash2(int l, int r){
    if(l > r) return 0;
    return (hash2[r] - (hash2[l - 1] * num2[r - l + 1]) % m2 + m2) % m2;
}

signed main(){
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> st[i];
    }
    init();
    sort(st + 1, st + 1 + n, cmp);
    for(int i = 1; i <= n; i++){
        int len = st[i].size();
        for(int j = 0; j < len; j++){
            tmp[j + 1] = st[i][j];
        }
        for(int j = 1; j <= len; j++){
            hash1[j] = (hash1[j - 1] * mod1 % m1 + (tmp[j] - 'a') + 122)%m1;
            hash2[j] = (hash2[j - 1] * mod2 % m2 + (tmp[j] - 'a') + 122) % m2;
        }
        for(int j = 1; j <= len - j + 1; j++){
            int t = len - j + 1;
            if(gethash1(1,j) == gethash1(t,len) && gethash2(1,j) == gethash2(t, len)){
                 ans += cnt[mp(gethash1(j + 1, t - 1), gethash2(j + 1, t - 1))];
            }
        }
        ans += cnt[mp(gethash1(1, len), gethash2(1, len))];
        cnt[mp(gethash1(1, len), gethash2(1, len))]++;
    }
    cout << ans;
    return 0;
} 

标签:return,num1,int,ll,后缀,Birthday,哈希,Cake,const
From: https://www.cnblogs.com/N-lim/p/16661409.html

相关文章

  • 242 有效的字母异位词(附带哈希的简单了解)
    哈希的简单了解https://www.bilibili.com/video/BV1bb4y1s7mw?p=62&vd_source=d6067928eb906629adf6cc260761df74题目242有效的字母异位词给定两个字符串s和t,编写......
  • Redis集群模式哈希槽rename问题
    (error)ERR'RENAME'commandkeysmustinsameslot一、介绍我们先来看基本的介绍RedisRename命令用于修改key的名称。1、语法redisrename命令的基本用法如......
  • 机器学习中的数值查找算法(3)——哈希查找算法
    原文链接:机器学习中的数值查找算法(3)——哈希查找算法–每天进步一点点(longkui.site)0.前言前面介绍的查找算法均是基于有序序列的查找方式,哈希查找是通过计算元素......
  • 28 | JAVA集合Properties专门用来存取配置文件(底层仍为哈希表)
    使用Properties配置文件的特点是,它的Key-Value一般都是String-String类型的,因此我们完全可以用Map<String,String>来表示它由于历史遗留原因,Properties内部本质上是一......
  • leetcode706-设计哈希映射
    设计哈希映射哈希+链表classMyHashMap{classPair{intkey;intvalue;publicPair(intkey,intvalue){this.key=......
  • 一致性哈希算法
    应用场景:分布式缓存架构中,典型的如Redis集群问题:2亿条数据要做缓存,如何设计?回复:单机肯定不行,需要用到分布式存储,可以使用redis,如何落地?方式1:哈希取余分区2亿条记录......
  • perl 数组嵌套入哈希内
    这里是指数组作为hash的value,即一个key对应多个值这里利用perl中的特殊句柄DATA做示例用以备忘{perl数据结构一旦复杂点,可读性急剧下降,坑......
  • 漫画:什么是一致性哈希?
     收录于合集         一年之前——       未来两年内,系统预估的总订单数量可达一亿条左右。 按Mysql单表存储500万条记......
  • 一致性哈希算法 consistent hashing
     在了解一致性哈希算法之前,最好先了解一下缓存中的一个应用场景,了解了这个应用场景之后,再来理解一致性哈希算法,就容易多了,也更能体现出一致性哈希算法的优点,那么,我们先......
  • H - Mr. Panda and Birthday Song Gym - 101775H
    题意:给你一个长度不大于1e6的字符串,由'a'-'z'或‘?’组成,且‘?’可转化为任意小写字母。和两个数x,y。现在有两个条件:字符串中存在任意一个长度为x的子串均为元音,或存在......