Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
competitive_programming/build/*
competitive_programming/test/env/*
**/build/*
**/env/*
.vscode/*
67 changes: 65 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,67 @@
# Competitive Programming C Plus Plus Library
<h1 align="center" style="font-weight: bold;">Competitive Programming C Plus Plus Library</h1>

A C++ library for competitive programming that includes a wide range of algorithms and data structures. Additionally, the project provides tests to ensure the correctness of its implementations.
<p align="center">
<a href="#tech">Technologies</a> •
<a href="#started">Getting Started</a> •
<a href="#contribute">Contribute</a>
</p>

<p align="center">
<b>A C++ library for competitive programming that includes a wide range of algorithms and data structures. Additionally, the project provides tests to ensure the correctness of its implementations.</b>
</p>

<h2 id="tech">💻 Technologies</h2>

- g++ 14
- Conan
- gtest


<h2 id="started">🚀 Getting started</h2>

<h3>Prerequisites</h3>

- g++ 14
- Python 3
- CMake

<h3>Cloning</h3>

How to clone your project

```bash
git clone https://github.com/ThiagoFBastos/Competitive-Programming-C-Plus-Plus-Library.git
```

<h3>Starting</h3>

How to start your project

```bash
cd competitive_programming
sudo apt install dos2unix
dos2unix ./scripts/install_deps.sh
dos2unix ./scripts/test.sh
sudo chmod +x ./scripts/install_deps.sh
sudo chmod +x ./scripts/test.sh
./scripts/install_deps.sh
```

How to run the tests

```bash
./scripts/test.sh
```

<h2 id="contribute">📫 Contribute</h2>

1. `git clone https://github.com/ThiagoFBastos/Competitive-Programming-C-Plus-Plus-Library.git`
2. `git checkout -b feature/NAME`
3. Follow commit patterns
4. Open a Pull Request explaining the problem solved or feature made, if exists, append screenshot of visual modifications and wait for the review!

<h3>Documentations that might help</h3>

[📝 How to create a Pull Request](https://www.atlassian.com/br/git/tutorials/making-a-pull-request)

[💾 Commit pattern](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716)
25 changes: 24 additions & 1 deletion competitive_programming/scripts/install_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,31 @@

set -e

BUILD_DIR=build
DIR="$(cd "$(dirname "$0")" && pwd)"

BUILD_DIR=$DIR/../build
BUILD_TYPE=Release
SRC=$DIR/..

cd $SRC

echo "==> Criando o ambiente virtual"
python3 -m venv env

echo "==> Ativando o ambiente virtual"
source ./env/bin/activate

echo "==> Instalando o Conan"
pip install conan

echo "==> Criando o Conan profile"
conan profile detect --force

export CC=gcc-14
export CXX=g++-14
export CONAN_SETTINGS_COMPILER=gcc
export CONAN_SETTINGS_COMPILER_VERSION=14
export CONAN_SETTINGS_COMPILER_LIBCXX=libstdc++11

echo "==> Instalando dependências (Conan)"
conan install . \
Expand Down
5 changes: 4 additions & 1 deletion competitive_programming/scripts/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

set -e

BUILD_DIR=build
DIR="$(cd "$(dirname "$0")" && pwd)"

BUILD_DIR=$DIR/../build


if [ -d $BUILD_DIR ]; then
echo "==> Compilando"
Expand Down
40 changes: 40 additions & 0 deletions competitive_programming/src/bitwise/maximum_xor_subset.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <vector>
#include <algorithm>

namespace bitset {

using value_type = unsigned long long;

inline value_type maximum_xor_subset(std::vector<value_type> arr) {
constexpr int max_bits = 64;

value_type result {};

for (int i = max_bits - 1; i >= 0; --i)
{
value_type max_element {};

for (const auto& num : arr)
{
if((num >> i) & 1)
max_element = std::max(max_element, num);
}

if(max_element == 0) continue;

if((result ^ max_element) > result)
result ^= max_element;

for(auto& num : arr)
{
if((num >> i) & 1)
num ^= max_element;
}
}

return result;
}

}
2 changes: 2 additions & 0 deletions competitive_programming/src/data_structures/dynamic_hull.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <set>
#include <functional>

/// FIXME
/// This data structure only handles queries of type (x, 1), which is incomplete
struct line
{
long long m, b;
Expand Down
53 changes: 53 additions & 0 deletions competitive_programming/src/dp/removal_game.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#pragma once

#include <vector>
#include <algorithm>
#include <numeric>
#include <array>

namespace dp
{

/**
* There is a list of n numbers and two players who move alternately.
* On each move, a player removes either the first or last number from the list,
* and their score increases by that number. Both players try to maximize their scores.
* What is the maximum possible score for the first player when both players play optimally?
* n <= 5000
* -10^9 <= nums[i] <= 10^9
* @param nums The list of numbers.
* @return The maximum possible score for the first player.
*/
inline long long removal_game(const std::vector<int>& nums)
{
const auto n = nums.size();
const auto sum = std::accumulate(nums.begin(), nums.end(), 0LL);
constexpr long long INF = 0x1000000000000LL;

std::vector<std::array<long long, 2>> dp(n, {0LL, 0LL});

std::size_t turn = ~n & 1;

for(std::size_t i = 0; i < n; ++i)
dp[i][turn] = nums[i];

for(std::size_t len = n - 1; len > 0; --len)
{
turn ^= 1;

std::size_t my = turn, your = turn ^ 1;

for(std::size_t i = 0; i < len; ++i)
dp[i][my] = -INF;

for(std::size_t i = 0; i < len; ++i)
dp[i][my] = std::max(dp[i][my], nums[i] - dp[i + 1][your]);

for(std::size_t i = 0; i < len; ++i)
dp[i][my] = std::max(dp[i][my], nums[i + n - len] - dp[i][your]);
}

return (sum + dp[0][0]) / 2;
}

}
32 changes: 32 additions & 0 deletions competitive_programming/src/dp/removing_digits.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include <vector>
#include <algorithm>

namespace dp
{

/**
* Given an integer n, return the minimum number of steps to reduce it to zero.
* In one step, you can remove any digit from n and subtract it from n.
*/
inline int removing_digits(int n)
{
std::vector<int> dp(n + 1);

dp[0] = 0;

for(int k = 1; k <= n; ++k)
{
int digit = 0;

for(int N = k; N > 0; N /= 10)
digit = std::max(N % 10, digit);

dp[k] = 1 + dp[k - digit];
}

return dp[n];
}

}
22 changes: 16 additions & 6 deletions competitive_programming/src/geometry/circle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,24 @@ inline circle minimumCircle(std::vector<point>& p)
std::shuffle(p.begin(), p.end(), rng);
int n = p.size();
circle C(p[0], 0.0);
for(int i = 0; i < n; ++i) {
if(C.contains(p[i])) continue;

for(int i = 0; i < n; ++i)
{
if(C.contains(p[i]))
continue;

C = circle(p[i], 0.0);
for(int j = 0; j < i; ++j) {
if(C.contains(p[j])) continue;
for(int j = 0; j < i; ++j)
{
if(C.contains(p[j]))
continue;

C = circle((p[j] + p[i]) * 0.5, 0.5 * dist(p[j], p[i]));
for(int k = 0; k < j; ++k) {
if(C.contains(p[k])) continue;
for(int k = 0; k < j; ++k)
{
if(C.contains(p[k]))
continue;

C = circumcircle(p[j], p[i], p[k]);
}
}
Expand Down
2 changes: 1 addition & 1 deletion competitive_programming/src/geometry/point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace geometry {

constexpr double EPS = 1e-9;
inline constexpr double EPS = 1e-9;

struct point
{
Expand Down
29 changes: 19 additions & 10 deletions competitive_programming/src/math/fft.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,31 @@ namespace math {

using cd = std::complex<double>;

inline void fft(std::vector<cd>& a, bool invert) {
inline void fft(std::vector<cd>& a, bool invert)
{
const double PI = std::acos(-1);

int n = a.size();

for(int i = 1, j = 0; i < n; ++i) {
for(int i = 1, j = 0; i < n; ++i)
{
int bit = n >> 1;
for(; j & bit; bit >>= 1) j -= bit;
j += bit;
if(i < j) std::swap(a[i], a[j]);
if(i < j)
std::swap(a[i], a[j]);
}

for(int len = 2; len <= n; len <<= 1) {
for(int len = 2; len <= n; len <<= 1)
{
double ang = 2 * PI / len * (invert ? -1 : 1);
cd wlen(std::cos(ang), std::sin(ang));
int mid = len >> 1;
for(int i = 0; i < n; i += len) {
for(int i = 0; i < n; i += len)
{
cd w(1);
for(int j = 0; j < mid; ++j) {
for(int j = 0; j < mid; ++j)
{
cd u = a[i + j], v = a[i + j + mid] * w;
a[i + j] = u + v;
a[i + j + mid] = u - v;
Expand All @@ -36,11 +42,12 @@ inline void fft(std::vector<cd>& a, bool invert) {
}
}

if(invert) for(int i = 0; i < n; ++i) a[i] /= n;
if(invert)
for(int i = 0; i < n; ++i) a[i] /= n;
}

inline void multiply(std::vector<int>& result, const std::vector<int>& a, const std::vector<int>& b) {

inline void multiply(std::vector<int>& result, const std::vector<int>& a, const std::vector<int>& b)
{
std::vector<cd> fa(a.begin(), a.end()), fb(b.begin(), b.end());

auto lg = [](int x) {
Expand All @@ -60,7 +67,9 @@ inline void multiply(std::vector<int>& result, const std::vector<int>& a, const
fft(fa, true);

result.resize(n);
for(int i = 0; i < n; ++i) result[i] = (int)std::round(fa[i].real());

for(int i = 0; i < n; ++i)
result[i] = (int)std::round(fa[i].real());
}

}
8 changes: 7 additions & 1 deletion competitive_programming/test/bitwise/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ add_executable(counting-bits counting_bits.cpp)
target_include_directories(counting-bits PRIVATE ${PROJECT_INCLUDE_DIR})
target_link_libraries(counting-bits PRIVATE GTest::gtest GTest::gtest_main)

# Maximum Xor Subset
add_executable(maximum-xor-subset maximum_xor_subset.cpp)
target_include_directories(maximum-xor-subset PRIVATE ${PROJECT_INCLUDE_DIR})
target_link_libraries(maximum-xor-subset PRIVATE GTest::gtest GTest::gtest_main)

include(GoogleTest)

gtest_discover_tests(counting-bits)
gtest_discover_tests(counting-bits)
gtest_discover_tests(maximum-xor-subset)
Loading
Loading