ku-library

This documentation is automatically generated by competitive-verifier/competitive-verifier

View the Project on GitHub kogetsu0728/ku-library

:warning: Next Combination (math/next_combination.hpp)

Depends on

Required by

Code

#pragma once

#include "../template/template.hpp"

/**
 * @brief Next Combination
 * @note 速度が重要なら再帰を書く (e.g., func(index, count, sum))
 */
template <class I>
bool next_combination(const I& begin, const I& end, const size_t k) {
    const I sub = next(begin, k);

    if (begin == end || begin == sub || end == sub) {
        return false;
    }

    I src = sub;
    while (begin != src) {
        advance(src, -1);

        if (*src < *prev(end, 1)) {
            I dst = sub;
            while (*dst <= *src) {
                advance(dst, 1);
            }

            iter_swap(src, dst);
            rotate(next(src, 1), next(dst, 1), end);
            rotate(sub, next(sub, distance(dst, end) - 1), end);

            return true;
        }
    }

    rotate(begin, sub, end);

    return false;
}
#line 2 "math/next_combination.hpp"

#line 2 "template/template.hpp"

/**
 * @author ku_senjan
 * @title 提出用テンプレート
 * @see https://github.com/kogetsu0728/ku-library
 */

#line 2 "template/constant.hpp"

#line 2 "template/include.hpp"

#ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
using namespace std;
#line 2 "template/type_alias.hpp"

#line 4 "template/type_alias.hpp"

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;

using ld = long double;

template <class T, bool REVERSE = false>
using heap = priority_queue<T, vector<T>, conditional_t<REVERSE, greater<T>, less<T>>>;
#line 5 "template/constant.hpp"

template <class T>
inline constexpr T INF = numeric_limits<T>::max() / 2;

inline constexpr array<int, 4> DY4 = {0, -1, 0, 1};
inline constexpr array<int, 4> DX4 = {1, 0, -1, 0};
inline constexpr array<int, 8> DY8 = {0, -1, -1, -1, 0, 1, 1, 1};
inline constexpr array<int, 8> DX8 = {1, 1, 0, -1, -1, -1, 0, 1};

inline constexpr char LF = '\n';
#line 2 "template/macro.hpp"

#line 5 "template/macro.hpp"

/**
 * @see https://trap.jp/post/1224/
 */

#ifdef LOCAL
inline constexpr bool IS_LOCAL = true;
#else
inline constexpr bool IS_LOCAL = false;
#endif

#define IF_LOCAL if constexpr (IS_LOCAL)

#define all(a) begin(a), end(a)
#define rall(a) rbegin(a), rend(a)

#define overload4(a, b, c, d, e, ...) e

#define rep1(i, a) for (ll i = 0; (i) < (ll)(a); ++(i))
#define rep2(i, a, b) for (ll i = (ll)(a); (i) < (ll)(b); ++(i))
#define rep3(i, a, b, c) for (ll i = (ll)(a); (i) < (ll)(b); (i) += (ll)(c))
#define rep(...) overload4(__VA_ARGS__, rep3, rep2, rep1)(__VA_ARGS__)

#define rrep1(i, a) for (ll i = (ll)(a); (i) >= 0; --(i))
#define rrep2(i, a, b) for (ll i = (ll)(a); (i) >= (ll)(b); --(i))
#define rrep3(i, a, b, c) for (ll i = (ll)(a); (i) >= (ll)(b); (i) -= (ll)(c))
#define rrep(...) overload4(__VA_ARGS__, rrep3, rrep2, rrep1)(__VA_ARGS__)
#line 13 "template/template.hpp"

#line 2 "utility/choose_min_max.hpp"

/**
 * @title Choose Minimum / Maximum
 */

template <class T>
bool chmin(T& a, const T& b) {
    if (a > b) {
        a = b;
        return true;
    }

    return false;
}

template <class T>
bool chmax(T& a, const T& b) {
    if (a < b) {
        a = b;
        return true;
    }

    return false;
}
#line 2 "utility/set_io.hpp"

#line 4 "utility/set_io.hpp"

void set_io(int d = 16) {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(d);

    return;
}
#line 4 "math/next_combination.hpp"

/**
 * @brief Next Combination
 * @note 速度が重要なら再帰を書く (e.g., func(index, count, sum))
 */
template <class I>
bool next_combination(const I& begin, const I& end, const size_t k) {
    const I sub = next(begin, k);

    if (begin == end || begin == sub || end == sub) {
        return false;
    }

    I src = sub;
    while (begin != src) {
        advance(src, -1);

        if (*src < *prev(end, 1)) {
            I dst = sub;
            while (*dst <= *src) {
                advance(dst, 1);
            }

            iter_swap(src, dst);
            rotate(next(src, 1), next(dst, 1), end);
            rotate(sub, next(sub, distance(dst, end) - 1), end);

            return true;
        }
    }

    rotate(begin, sub, end);

    return false;
}
Back to top page