Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
sunkafei committed Jun 7, 2024
1 parent b070f2e commit 03c7d30
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@
- 排列组合枚举
- 动态维护连续相同数字区间
- 二分查找
- 计时器
- 动态数组
- 匹配算法
- 匈牙利算法
- KM算法
- 带花树算法
- 高精度
- 大整数类
- 分数类
- 高精度定点数
- 动态规划
- 斯坦纳树(点权)
- 斯坦纳树(边权)
Expand Down
Binary file removed XCPC算法模板(2024-03-29).pdf
Binary file not shown.
Binary file added XCPC算法模板(2024-06-07).pdf
Binary file not shown.
86 changes: 86 additions & 0 deletions 算法/基础算法/动态数组.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <ranges>
#include <cassert>
#include <cstdio>
template<typename T, int maxsize>
class darray : public std::ranges::view_interface<darray<T, maxsize>> {
private:
T data[maxsize];
int sz;
public:
darray() : sz(0) {}
darray(const darray& rhs) noexcept : sz(rhs.sz) {
copy(rhs.begin(), rhs.begin() + sz, data);
}
darray& operator= (const darray& rhs) noexcept {
sz = rhs.sz;
copy(rhs.begin(), rhs.begin() + sz, data);
return *this;
}
void push_back(T val) noexcept {
assert(sz < maxsize);
data[sz++] = std::move(val);
}
void expand() noexcept {
assert(sz < maxsize);
sz += 1;
}
void erase(T val) noexcept {
for (int i = 0; i < sz; ++i) {
if (data[i] == val) {
data[i] = std::move(data[sz - 1]);
sz -= 1;
return;
}
}
}
void replace(T old_val, T new_val) noexcept {
for (int i = 0; i < sz; ++i) {
if (data[i] == old_val) {
data[i] = new_val;
return;
}
}
}
void set(T val) noexcept {
data[0] = val;
sz = 1;
}
bool contains(T val) const noexcept {
for (int i = 0; i < sz; ++i) {
if (data[i] == val) {
return true;
}
}
return false;
}
void pop_back() {
assert(sz > 0);
sz -= 1;
}
void clear() noexcept {
sz = 0;
}
auto* begin() noexcept {
return data;
}
auto* end() noexcept {
return data + sz;
}
const auto* begin() const noexcept {
return data;
}
const auto* end() const noexcept {
return data + sz;
}
};
int main() {
darray<int, 100> arr;
for (int i = 0; i < 50; ++i) {
arr.push_back(i);
}
for (int i = 1; i < 50; ++i) {
arr[i] += arr[i - 1];
}
std::printf("%d %d %d\n", (int)arr.size(), arr.front(), arr[30]);
return 0;
}
20 changes: 20 additions & 0 deletions 算法/基础算法/计时器.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <iostream>
#include <chrono>
#include <set>
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() {
Timer timer;
std::set<int> S;
for (int i = 0; i < 1e6; ++i) {
S.insert(i);
}
return 0;
}
152 changes: 152 additions & 0 deletions 算法/高精度/高精度定点数.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#include <iostream>
#include <cstdio>
#include <array>
class fixed { // 高精度定点数
private:
static constexpr int num_blocks = 40;
static constexpr int offset = (num_blocks / 2) * 64;
std::array<uint64_t, num_blocks> data = {};
public:
fixed(double value) {
uint64_t bits = *(uint64_t*)&value;
uint64_t fraction = bits & 0xfffffffffffff;
uint64_t exponent = (bits & 0x7ff0000000000000) >> 52;
uint64_t sign = bits >> 63;
if (exponent != 0) {
exponent -= 1023;
fraction |= (1ull << 52);
}
else {
exponent = -1022;
}
exponent += offset - 52;
data[exponent / 64] |= (fraction << (exponent % 64));
fraction <<= 11;
data[(exponent + 52) / 64] |= (fraction >> (63 - (exponent + 52) % 64));
if (sign) {
for (int i = 0; i < num_blocks; ++i) {
data[i] = ~data[i];
}
for (int i = 0; i < num_blocks; ++i) {
data[i] += 1;
if (data[i]) {
break;
}
}
}
}
explicit operator double() const {
decltype(this->data) data = this->data;
uint64_t sign = 0;
if (data[num_blocks - 1] & (1ull << 63)) {
sign = 1;
for (int i = 0; i < num_blocks; ++i) {
data[i] = ~data[i];
}
for (int i = 0; i < num_blocks; ++i) {
data[i] += 1;
if (data[i]) {
break;
}
}
}
int64_t top = -1;
for (int i = num_blocks - 1; i >= 0; --i) {
if (data[i]) {
for (int j = 63; j >= 0; --j) {
if (data[i] & (1ull << j)) {
top = i * 64 + j;
goto finish;
}
}
}
}
if (top == -1) {
return 0;
}
finish:;
int64_t exponent = top - offset + 1023;
uint64_t fraction = 0;
if (exponent >= 2047) {
exponent = 2047;
}
else {
for (int i = 1; i <= 52; ++i) {
auto block = (top - i) / 64;
auto num = (top - i) % 64;
if (data[block] & (1ull << num)) {
fraction |= (1ull << (52 - i));
}
}
uint64_t carry = 0;
if (data[(top - 53) / 64] & (1ull << ((top - 53) % 64))) {
for (int i = 54; i <= 54 + 64; ++i) {
auto block = (top - i) / 64;
auto num = (top - i) % 64;
if (data[block] & (1ull << num)) {
carry = 1;
break;
}
}
if (!carry) {
auto block = (top - 53) / 64;
for (int i = 0; i < block; ++i) if (data[i]) {
carry = 1;
break;
}
}
if (!carry) {
if (fraction & 1) {
carry = 1;
}
}
}
fraction += carry;
if (fraction > 0xfffffffffffff) {
fraction = 0;
exponent += 1;
}
if (exponent <= 0) {
fraction |= (1ull << 52);
fraction >>= -exponent + 1;
exponent = 0;
}
}
fraction &= 0xfffffffffffff;
uint64_t ret = (sign << 63) | (exponent << 52) | fraction;
return *(double*)&ret;
}
void operator+= (const fixed& rhs) {
uint64_t overflow = 0;
for (int i = 0; i < num_blocks; ++i) {
uint64_t value = rhs.data[i] + overflow;
if (value < overflow) {
overflow = 1;
}
else {
overflow = 0;
}
data[i] += value;
if (data[i] < value) {
overflow = 1;
}
}
}
fixed operator+ (const fixed& rhs) const {
fixed ret = *this;
ret += rhs;
return ret;
}
void debug() const {
for (int i = 0; i < num_blocks; ++i) {
for (int j = 0; j < 64; ++j) {
if (data[i] & (1ull << j)) {
printf("bit: %d\n", i * 64 + j - offset);
}
}
}
}
};
int main() {
return 0;
}

0 comments on commit 03c7d30

Please sign in to comment.