proconlib

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

View the Project on GitHub anqooqie/proconlib

:heavy_check_mark: Superset Möbius transform (tools/superset_moebius.hpp)

(1)
template <typename InputIterator, typename OutputIterator>
void superset_moebius(InputIterator begin, InputIterator end, OutputIterator result);

(2)
template <typename RandomAccessIterator>
void superset_moebius(RandomAccessIterator begin, RandomAccessIterator end);

The following relationship holds between $a$ and $b$.

\[\begin{align*} b_i &= \sum_{\substack{0 \leq j < N \\ (i~\mathrm{AND}~j) = i}} a_j \end{align*}\]

Constraints

Time Complexity

License

Author

Depends on

Required by

Verified with

Code

#ifndef TOOLS_SUPERSET_MOEBIUS_HPP
#define TOOLS_SUPERSET_MOEBIUS_HPP

#include <iterator>
#include <vector>
#include <algorithm>
#include "tools/pow2.hpp"

namespace tools {
  template <typename RandomAccessIterator>
  void superset_moebius(const RandomAccessIterator begin, const RandomAccessIterator end) {
    const int N = end - begin;

    for (int w = 0; ::tools::pow2(w) < N; ++w) {
      for (int i = 0; ; i += ::tools::pow2(w)) {
        for (; !((i >> w) & 1); ++i) {
          if (!(i + ::tools::pow2(w) < N)) goto NEXT_W;
          begin[i] -= begin[i + ::tools::pow2(w)];
        }
      }
    NEXT_W:
      ;
    }
  }

  template <typename InputIterator, typename OutputIterator>
  void superset_moebius(const InputIterator begin, const InputIterator end, const OutputIterator result) {
    using T = typename ::std::iterator_traits<InputIterator>::value_type;
    ::std::vector<T> b(begin, end);
    ::tools::superset_moebius(b.begin(), b.end());
    ::std::move(b.begin(), b.end(), result);
  }
}

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



#include <iterator>
#include <vector>
#include <algorithm>
#line 1 "tools/pow2.hpp"



#include <type_traits>
#include <cstddef>

namespace tools {

  template <typename T, typename ::std::enable_if<::std::is_unsigned<T>::value, ::std::nullptr_t>::type = nullptr>
  constexpr T pow2(const T x) {
    return static_cast<T>(1) << x;
  }

  template <typename T, typename ::std::enable_if<::std::is_signed<T>::value, ::std::nullptr_t>::type = nullptr>
  constexpr T pow2(const T x) {
    return static_cast<T>(static_cast<typename ::std::make_unsigned<T>::type>(1) << static_cast<typename ::std::make_unsigned<T>::type>(x));
  }
}


#line 8 "tools/superset_moebius.hpp"

namespace tools {
  template <typename RandomAccessIterator>
  void superset_moebius(const RandomAccessIterator begin, const RandomAccessIterator end) {
    const int N = end - begin;

    for (int w = 0; ::tools::pow2(w) < N; ++w) {
      for (int i = 0; ; i += ::tools::pow2(w)) {
        for (; !((i >> w) & 1); ++i) {
          if (!(i + ::tools::pow2(w) < N)) goto NEXT_W;
          begin[i] -= begin[i + ::tools::pow2(w)];
        }
      }
    NEXT_W:
      ;
    }
  }

  template <typename InputIterator, typename OutputIterator>
  void superset_moebius(const InputIterator begin, const InputIterator end, const OutputIterator result) {
    using T = typename ::std::iterator_traits<InputIterator>::value_type;
    ::std::vector<T> b(begin, end);
    ::tools::superset_moebius(b.begin(), b.end());
    ::std::move(b.begin(), b.end(), result);
  }
}


Back to top page