proconlib

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

View the Project on GitHub anqooqie/proconlib

:heavy_check_mark: Coordinate compression (tools/compressed.hpp)

(1)
template <tools::integral T, std::ranges::input_range R>
requires std::totally_ordered<std::ranges::range_value_t<R>>
std::vector<T> compressed(R&& a);

(2)
template <std::ranges::input_range R>
requires std::totally_ordered<std::ranges::range_value_t<R>>
std::vector<std::conditional_t<tools::integral<std::ranges::range_value_t<R>>, std::ranges::range_value_t<R>, int>> compressed(R&& a);

Constraints

Time Complexity

License

Author

Depends on

Required by

Verified with

Code

#ifndef TOOLS_COMPRESSED_HPP
#define TOOLS_COMPRESSED_HPP

#include <algorithm>
#include <concepts>
#include <ranges>
#include <type_traits>
#include <utility>
#include <vector>
#include "tools/integral.hpp"
#include "tools/lower_bound.hpp"

namespace tools {
  template <tools::integral T, std::ranges::input_range R>
  requires std::totally_ordered<std::ranges::range_value_t<R>>
  std::vector<T> compressed(R&& a) {
    if constexpr (std::ranges::forward_range<R>) {
      auto sorted = a | std::ranges::to<std::vector>();
      std::ranges::sort(sorted);
      sorted.erase(std::unique(sorted.begin(), sorted.end()), sorted.end());
      return std::forward<R>(a) | std::views::transform([&](const auto& a_i) { return tools::lower_bound(sorted, a_i); }) | std::ranges::to<std::vector<T>>();
    } else {
      return tools::compressed<T>(std::forward<R>(a) | std::ranges::to<std::vector>());
    }
  }

  template <std::ranges::input_range R>
  requires std::totally_ordered<std::ranges::range_value_t<R>>
  std::vector<std::conditional_t<tools::integral<std::ranges::range_value_t<R>>, std::ranges::range_value_t<R>, int>> compressed(R&& a) {
    return tools::compressed<std::conditional_t<tools::integral<std::ranges::range_value_t<R>>, std::ranges::range_value_t<R>, int>>(std::forward<R>(a));
  }
}

#endif
#line 1 "tools/compressed.hpp"



#include <algorithm>
#include <concepts>
#include <ranges>
#include <type_traits>
#include <utility>
#include <vector>
#line 1 "tools/integral.hpp"



#line 1 "tools/is_integral.hpp"



#line 5 "tools/is_integral.hpp"

namespace tools {
  template <typename T>
  struct is_integral : std::is_integral<T> {};

  template <typename T>
  inline constexpr bool is_integral_v = tools::is_integral<T>::value;
}


#line 5 "tools/integral.hpp"

namespace tools {
  template <typename T>
  concept integral = tools::is_integral_v<T>;
}


#line 1 "tools/lower_bound.hpp"



#line 5 "tools/lower_bound.hpp"
#include <functional>
#include <iterator>
#line 8 "tools/lower_bound.hpp"

namespace tools {

  template <
    std::random_access_iterator I,
    std::sentinel_for<I> S,
    typename Proj = std::identity,
    typename T = std::remove_cvref_t<std::invoke_result_t<Proj&, std::iter_value_t<I>&>>,
    std::indirect_strict_weak_order<const T*, std::projected<I, Proj>> Comp = std::ranges::less
  >
  constexpr std::iter_difference_t<I> lower_bound(const I first, const S last, const T& value, const Comp comp = {}, const Proj proj = {}) {
    return std::ranges::distance(first, std::ranges::lower_bound(first, last, value, comp, proj));
  }

  template <
    std::ranges::random_access_range R,
    typename Proj = std::identity,
    typename T = std::remove_cvref_t<std::invoke_result_t<Proj&, std::ranges::range_value_t<R>&>>,
    std::indirect_strict_weak_order<const T*, std::projected<std::ranges::iterator_t<R>, Proj>> Comp = std::ranges::less
  >
  constexpr std::ranges::range_difference_t<R> lower_bound(R&& r, const T& value, const Comp comp = {}, const Proj proj = {}) {
    return std::ranges::distance(std::ranges::begin(r), std::ranges::lower_bound(r, value, comp, proj));
  }
}


#line 12 "tools/compressed.hpp"

namespace tools {
  template <tools::integral T, std::ranges::input_range R>
  requires std::totally_ordered<std::ranges::range_value_t<R>>
  std::vector<T> compressed(R&& a) {
    if constexpr (std::ranges::forward_range<R>) {
      auto sorted = a | std::ranges::to<std::vector>();
      std::ranges::sort(sorted);
      sorted.erase(std::unique(sorted.begin(), sorted.end()), sorted.end());
      return std::forward<R>(a) | std::views::transform([&](const auto& a_i) { return tools::lower_bound(sorted, a_i); }) | std::ranges::to<std::vector<T>>();
    } else {
      return tools::compressed<T>(std::forward<R>(a) | std::ranges::to<std::vector>());
    }
  }

  template <std::ranges::input_range R>
  requires std::totally_ordered<std::ranges::range_value_t<R>>
  std::vector<std::conditional_t<tools::integral<std::ranges::range_value_t<R>>, std::ranges::range_value_t<R>, int>> compressed(R&& a) {
    return tools::compressed<std::conditional_t<tools::integral<std::ranges::range_value_t<R>>, std::ranges::range_value_t<R>, int>>(std::forward<R>(a));
  }
}


Back to top page