如何在 C++ 中自制头文件?
方法
操作十分的简单
只用将你要做的部分放进下面这个板子就行了:
#ifndef FILE_NAME_HPP
#define FILE_NAME_HPP
// 防止重复包含(兼容所有编译器)
// 放你的代码
// 不要有 main 函数
#endif
做完过后将这份文件保存为: .hpp,注意是 hpp
就像这份:
View Code
#ifndef FENWICK_TREE_HPP
#define FENWICK_TREE_HPP
#include <bits/stdc++.h>
using ll = long long;
namespace Fenwick_Tree {
const int maxn = 2e6 + 5;
struct FenwickTree {
ll tree[maxn];
int lowbit(int x) {
return x & -x;
}
void update(int pos, ll val) {
for (; pos < maxn; pos += lowbit(pos))
tree[pos] += val;
}
ll query(int pos) {
ll res = 0;
for (; pos > 0; pos -= lowbit(pos))
res += tree[pos];
return res;
}
ll query_interval(int L, int R) {
if (L > R) return 0;
return query(R) - query(L - 1);
}
void reset() {
memset(tree, 0, sizeof(tree));
}
};
};
#endif
访问时只需要保证在同一目录下即可
像这样子访问:
View Code
#include "Fenwick_Tree.hpp"
int main() {
return 0;
}
也是很简单了
用处
当你要大量用同一份板子,同时又希望代码简洁是即可使用
或者说是代码过于冗长,将自己拿得准的模版部分做成头文件,然后再调试
就像这份 van Emde Boas 树的代码,做成头文件后代码中只用加上两三行
View Code
#ifndef VEB_TREE_HPP
#define VEB_TREE_HPP
#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <unordered_map>
#include <functional>
#include <stdexcept>
#include <algorithm>
#include <string>
using namespace std;
namespace van_Emde_Boas_Tree {
const int NILL = -1;
const int MAX_NODE = 1e6;
int cnt = 0;
unordered_map<int, int> log_table;
struct van_Emde_Boas {
int u;
int summary;
vector<int> cluster;
int max_val, min_val;
van_Emde_Boas() : u(0), summary(NILL), max_val(NILL), min_val(NILL) {}
};
vector<van_Emde_Boas> vEB;
void init() {
cnt = 0;
log_table.clear();
vEB.clear();
vEB.reserve(MAX_NODE);
for (int i = 0; i < 32; i++) {
log_table[1 << i] = i;
}
}
int new_node() {
// if (cnt >= MAX_NODE) { // debug
// cerr << "Error: Node count exceeds MAX_NODE!" << "\n";
// exit(1);
// }
vEB.emplace_back();
return cnt++;
}
int high(int root, int x) {
int u = 1 << (log_table[vEB[root].u] >> 1);
return x / u;
}
int low(int root, int x) {
int u = 1 << (log_table[vEB[root].u] >> 1);
return x % u;
}
int index(int root, int x, int y) {
int u = 1 << (log_table[vEB[root].u] >> 1);
return x * u + y;
}
void build(int root, int size) {
vEB[root].summary = NILL;
vEB[root].min_val = NILL;
vEB[root].max_val = NILL;
if (size <= 1) {
vEB[root].u = 2;
return;
}
vEB[root].u = 1 << size;
int cluster_size = (size >> 1) + (size & 1);
int summary_node = new_node();
vEB[root].summary = summary_node;
build(summary_node, cluster_size);
int cluster_cnt = 1 << cluster_size;
vEB[root].cluster.resize(cluster_cnt);
for (int i = 0; i < cluster_cnt; i++) {
int child = new_node();
vEB[root].cluster[i] = child;
build(child, size >> 1);
}
}
int minimum(int root) {
return vEB[root].min_val;
}
int maximum(int root) {
return vEB[root].max_val;
}
bool member(int root, int x) {
if (x < 0 || x >= vEB[root].u) return false;
if (x == vEB[root].min_val || x == vEB[root].max_val) return true;
if (vEB[root].u == 2) return false;
return member(vEB[root].cluster[high(root, x)], low(root, x));
}
int successor(int root, int x) {
if (vEB[root].u == 2) {
if (x == 0 && vEB[root].max_val == 1) return 1;
return NILL;
}
if (vEB[root].min_val != NILL && x < vEB[root].min_val) return vEB[root].min_val;
int max_low = maximum(vEB[root].cluster[high(root, x)]);
if (max_low != NILL && low(root, x) < max_low) {
int offset = successor(vEB[root].cluster[high(root, x)], low(root, x));
return index(root, high(root, x), offset);
}
int successor_cluster = successor(vEB[root].summary, high(root, x));
if (successor_cluster == NILL) return NILL;
int offset = minimum(vEB[root].cluster[successor_cluster]);
return index(root, successor_cluster, offset);
}
int predecessor(int root, int x) {
if (vEB[root].u == 2) {
if (x == 1 && vEB[root].min_val == 0) return 0;
return NILL;
}
if (vEB[root].max_val != NILL && x > vEB[root].max_val) return vEB[root].max_val;
int min_low = minimum(vEB[root].cluster[high(root, x)]);
if (min_low != NILL && low(root, x) > min_low) {
int offset = predecessor(vEB[root].cluster[high(root, x)], low(root, x));
return index(root, high(root, x), offset);
}
int predecessor_cluster = predecessor(vEB[root].summary, high(root, x));
if (predecessor_cluster == NILL) {
if (vEB[root].min_val != NILL && x > vEB[root].min_val) return vEB[root].min_val;
return NILL;
}
int offset = maximum(vEB[root].cluster[predecessor_cluster]);
return index(root, predecessor_cluster, offset);
}
void empty_insert(int root, int x) {
vEB[root].max_val = vEB[root].min_val = x;
}
void insert(int root, int x) {
if (x < 0 || x >= vEB[root].u) return;
if (vEB[root].min_val == NILL) {
empty_insert(root, x);
return;
}
if (x < vEB[root].min_val) swap(x, vEB[root].min_val);
if (vEB[root].u > 2) {
int h = high(root, x);
int l = low(root, x);
int child = vEB[root].cluster[h];
if (minimum(child) == NILL) {
insert(vEB[root].summary, h);
empty_insert(child, l);
} else {
insert(child, l);
}
}
if (x > vEB[root].max_val) vEB[root].max_val = x;
}
void erase(int root, int x) {
if (x < 0 || x >= vEB[root].u) return;
if (vEB[root].min_val == vEB[root].max_val) {
vEB[root].min_val = vEB[root].max_val = NILL;
return;
}
if (vEB[root].u == 2) {
vEB[root].min_val = vEB[root].max_val = (x == 0) ? 1 : 0;
return;
}
if (x == vEB[root].min_val) {
int first_cluster = minimum(vEB[root].summary);
if (first_cluster == NILL) {
vEB[root].min_val = vEB[root].max_val = NILL;
return;
}
int child = vEB[root].cluster[first_cluster];
int new_min = index(root, first_cluster, minimum(child));
vEB[root].min_val = new_min;
x = new_min;
}
int h = high(root, x);
int l = low(root, x);
int child = vEB[root].cluster[h];
erase(child, l);
if (minimum(child) == NILL) {
erase(vEB[root].summary, h);
if (x == vEB[root].max_val) {
int summary_max = maximum(vEB[root].summary);
if (summary_max == NILL) {
vEB[root].max_val = vEB[root].min_val;
} else {
int max_child = vEB[root].cluster[summary_max];
vEB[root].max_val = index(root, summary_max, maximum(max_child));
}
}
} else if (x == vEB[root].max_val) {
vEB[root].max_val = index(root, h, maximum(child));
}
}
}
#endif
同样,在开发项目中也挺好用,应该是吧

浙公网安备 33010602011771号