競技プログラミング用の C++ ライブラリ
#include "src/data_structures/circular-ring.hpp"添字を長さで割った余りでアクセスできる配列です。負の添字も使えます。
CircularRing<int> r(std::vector<int>{10, 20, 30});
int a = r[3]; // 10
int b = r[-1]; // 30
r[-1] = 99; // data = {10, 20, 99}
| メンバ | 説明 | 計算量 |
|---|---|---|
CircularRing<T>(v) |
v で初期化 |
$O(n)$ |
CircularRing<T>(n) |
長さ n で、要素は T()
|
$O(n)$ |
r[i] / r.at(i)
|
$i \bmod n$ 番目の要素 (long long の添字、負でもよい) |
$O(1)$ |
r.data |
中身の std::vector<T>
|
#pragma once
/**
* @file circular-ring.hpp
* @brief 円環
*/
#include <cassert>
#include <vector>
/**
* @brief 円環
* @tparam T
*/
template <typename T>
struct CircularRing {
std::vector<T> data;
CircularRing(const std::vector<T>& v) : data(v) {}
CircularRing(const CircularRing&) = default;
CircularRing() = default;
CircularRing(size_t s) : data(s) {}
T at(long long i) const {
assert(!data.empty());
i %= static_cast<long long>(data.size());
if (i < 0) i += static_cast<long long>(data.size());
return data[i];
}
T& at(long long i) {
assert(!data.empty());
i %= static_cast<long long>(data.size());
if (i < 0) i += static_cast<long long>(data.size());
return data[i];
}
T operator[](long long i) const {
return at(i);
}
T& operator[](long long i) {
return at(i);
}
};#line 2 "src/data_structures/circular-ring.hpp"
/**
* @file circular-ring.hpp
* @brief 円環
*/
#include <cassert>
#include <vector>
/**
* @brief 円環
* @tparam T
*/
template <typename T>
struct CircularRing {
std::vector<T> data;
CircularRing(const std::vector<T>& v) : data(v) {}
CircularRing(const CircularRing&) = default;
CircularRing() = default;
CircularRing(size_t s) : data(s) {}
T at(long long i) const {
assert(!data.empty());
i %= static_cast<long long>(data.size());
if (i < 0) i += static_cast<long long>(data.size());
return data[i];
}
T& at(long long i) {
assert(!data.empty());
i %= static_cast<long long>(data.size());
if (i < 0) i += static_cast<long long>(data.size());
return data[i];
}
T operator[](long long i) const {
return at(i);
}
T& operator[](long long i) {
return at(i);
}
};