哈希表的循环数不能是偶数
查看原帖
哈希表的循环数不能是偶数
151374
Anan2楼主2023/11/21 18:40

被坑了

而且stl自带的hash函数抗碰撞太差,拿上去会喜得45


#include <iostream>
#include <fstream>
#include <string>
#include <unordered_map>

std::string str;
auto &game_in = std::cin;
auto &game_out = std::cout;
// std::ifstream game_in("game.in");
// std::ofstream game_out("game.out");
size_t hashtable[size_t(2e6)] = {1, 0};

std::string buffer;
size_t seed = 0;
constexpr void make_hashtable()
{
    for (size_t i = 1; i < 2e6; i++)
        hashtable[i] = hashtable[i - 1] * 73556087355607; // 这个数还不能是偶数
}
inline size_t hash(const std::string &t)
{
    // return std::hash<size_t>()(t.length()) * (t.empty() ? 0 : t.back());
    return hashtable[t.length()] * t.back();
}
std::unordered_map<size_t, int> prefix_str_times({{0, 1}});

uint64_t find_substr()
{
    uint64_t ans = 0;
    for (const auto &i : str)
    {
        if (!buffer.empty() && buffer.back() == i)
        {
            seed -= hash(buffer);
            buffer.pop_back();
        }
        else
        {
            buffer.push_back(i);
            seed += hash(buffer);
        }
        ans += prefix_str_times[seed];
        prefix_str_times[seed]++;
    }
    return ans;
}

int main(void)
{
    using namespace std;
    ios::sync_with_stdio(false);
    make_hashtable();
    size_t _;
    game_in >> _ >> str;
    game_out << find_substr();
    return 0;
}
2023/11/21 18:40
加载中...