shogo-library

競技プログラミング用の C++ ライブラリ

View the Project on GitHub shogo314/shogo-library

:heavy_check_mark: 円環
(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>  

関連

Verified with

Code

#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);
    }
};
Back to top page