---
url: /algo/755fzvzc/index.md
---
::: warning 警告
本模板为了便于理解，包含了大量的详细注释以及规范的 `std::` 命名空间前缀。在您将代码复制并提交至相关竞赛或评测平台前，请务必根据个人的编程习惯进行调整，重点建议删除冗余注释并精简代码风格。保留明显的模板特征极易被系统的查重算法或 AIGC 监测机制误标为“人工智能生成内容”，从而对您的评审进度或最终成绩产生不利影响。
:::

## 代码计时器

配合数据生成器生成极端数据效果更佳，可以计算程序跑的时间。

```cpp title="timer.cc" :collapsed-lines
struct Timer
{
    std::chrono::steady_clock::time_point start;
    Timer() : start(std::chrono::steady_clock::now()) {}
    ~Timer()
    {
        auto finish = std::chrono::steady_clock::now();
        auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count();
        std::cerr << runtime / 1e6 << "s" << std::endl;
    }
};
int main()
{
    int a;
    std::cin >> a;
    // 读入在前面完成或者使用重定向
    Timer timer; // 从这里开始计时
    std::set<int> S;
    for (int i = 0; i < 1e6; ++i)
    {
        S.insert(i);
    }
    return 0;
}
```

## 数据生成器

可以借此生成极端数据丢给计时器看运行时间。

```cpp title="generator.cc" :collapsed-lines
template <typename T>
std::vector<T> genRandoms(T left, T right, int counts)
{
    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<T> distribution(left, right);
    std::vector<T> v;
    for (int i = 0; i < counts; i++)
    {
        v.push_back(distribution(generator));
    }
    return v;
}

int main()
{
    auto v = genRandoms(1ll, 1145141919810ll, 10);
    for (auto i : v)
    {
        std::cout << i << " ";
    }
    return 0;
}
```

## Pair 哈希

```cpp title="pairhash.cc" :collapsed-lines
using namespace std;

template <typename T1, typename T2>
struct PairHash
{
    size_t operator()(const pair<T1, T2> &p) const
    {
        auto hash1 = hash<T1>{}(p.first);
        auto hash2 = hash<T2>{}(p.second);

        size_t seed = 0;
        seed ^= hash1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
        seed ^= hash2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);

        return seed;
    }
};

// 使用示例
unordered_set<pair<int, int>, PairHash<int, int>> mySet;
```

## Tuple 哈希

```cpp title="pairhash.cc" :collapsed-lines
template <typename T>
void hash_combine(std::size_t &seed, const T &val)
{
    seed ^= std::hash<T>{}(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

template <typename... Types>
std::size_t hash_tuple(const std::tuple<Types...> &tuple)
{
    std::size_t seed = 0;
    std::apply([&seed](const auto &...args)
               { (hash_combine(seed, args), ...); }, tuple);
    return seed;
}

namespace std
{
    template <typename... Types>
    struct hash<std::tuple<Types...>>
    {
        std::size_t operator()(const std::tuple<Types...> &tuple) const
        {
            return hash_tuple(tuple);
        }
    };
}

int main()
{
    std::unordered_set<std::tuple<int, std::string, double>> mySet;

    mySet.emplace(1, "hello", 3.14);
    mySet.emplace(2, "world", 2.71);
    mySet.emplace(1, "hello", 3.14); // 重复，不会被插入

    std::cout << "Set size: " << mySet.size() << std::endl; // 输出 2

    return 0;
}
```

## 字符串流

将字符串当作 stream 使用

```cpp title="stringstream.cc" :collapsed-lines
#include <bits/stdc++.h>
using namespace std;

int main()
{
    string s = "12 34 56";
    int a, b, c;
    stringstream ss;
    ss << s; // 流式输出到 ss
    ss >> a >> b >> c; // 流式输入给 a, b, c
    return 0;
}
```
