cpp-library

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

View the Project on GitHub shino16/cpp-library

:warning: la/vec.hpp

Depends on

Required by

Code

#pragma once
#include "prelude.hpp"

template <class T, class U, class F, size_t... Is>
void zip_with_impl(T&& a, U&& b, F f, index_sequence<Is...>) {
  (f(get<Is>(a), get<Is>(b)), ...);
}

template <class T, class U, class F>
void zip_with(T&& a, U&& b, F f) {
  zip_with_impl(
      forward<T>(a), forward<U>(b), f,
      make_index_sequence<tuple_size_v<decay_t<T>>>{});
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T& operator+=(T& a, const U& b) {
  zip_with(a, b, [](auto&& x, auto&& y) { x += y; });
  return a;
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T& operator-=(T& a, const U& b) {
  zip_with(a, b, [](auto&& x, auto&& y) { x -= y; });
  return a;
}

template <class T, class U>
T& operator*=(T& a, U r) {
  for_each(all(a), [=](auto& x) { x *= r; });
  return a;
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T operator+(const T& a, const U& b) {
  T c(a);
  c += b;
  return c;
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T operator-(const T& a, const U& b) {
  T c(a);
  c -= b;
  return c;
}

template <class T, class U>
T operator*(U r, const T& a) {
  T c(a);
  c *= r;
  return c;
}

template <class T, class E = tuple_element_t<0, T>>
E dot(const T& a, const T& b) {
  E res(0);
  zip_with(a, b, [&](auto&& x, auto&& y) { res += x * y; });
  return res;
}

template <class T, enable_if_t<tuple_size_v<T> == 2>* = nullptr>
auto det(const T& a, const T& b) {
  return get<0>(a) * get<1>(b) - get<1>(a) * get<0>(b);
}

// Returns k s.t. a == kb
// k=inf if b == 0
template <class T>
double factor(const T& a, const T& b) {
  double res = numeric_limits<double>::infinity();
  assert(dot(a, b) == 0);
  zip_with(a, b, [&](auto&&x, auto&& y) {
    if (y) res = x / y;
  });
  return res;
}
#line 2 "prelude.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vc = vector<char>;
#define rep2(i, m, n) for (auto i = (m); i < (n); i++)
#define rep(i, n) rep2(i, 0, n)
#define repr2(i, m, n) for (auto i = (n); i-- > (m);)
#define repr(i, n) repr2(i, 0, n)
#define all(x) begin(x), end(x)
auto ndvec(int n, auto e) { return vector(n, e); }
auto ndvec(int n, auto ...e) { return vector(n, ndvec(e...)); }
auto comp_key(auto&& f) { return [&](auto&& a, auto&& b) { return f(a) < f(b); }; }
auto& max(const auto& a, const auto& b) { return a < b ? b : a; }
auto& min(const auto& a, const auto& b) { return b < a ? b : a; }
#if __cpp_lib_ranges
namespace R = std::ranges;
namespace V = std::views;
#endif
#line 3 "la/vec.hpp"

template <class T, class U, class F, size_t... Is>
void zip_with_impl(T&& a, U&& b, F f, index_sequence<Is...>) {
  (f(get<Is>(a), get<Is>(b)), ...);
}

template <class T, class U, class F>
void zip_with(T&& a, U&& b, F f) {
  zip_with_impl(
      forward<T>(a), forward<U>(b), f,
      make_index_sequence<tuple_size_v<decay_t<T>>>{});
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T& operator+=(T& a, const U& b) {
  zip_with(a, b, [](auto&& x, auto&& y) { x += y; });
  return a;
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T& operator-=(T& a, const U& b) {
  zip_with(a, b, [](auto&& x, auto&& y) { x -= y; });
  return a;
}

template <class T, class U>
T& operator*=(T& a, U r) {
  for_each(all(a), [=](auto& x) { x *= r; });
  return a;
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T operator+(const T& a, const U& b) {
  T c(a);
  c += b;
  return c;
}

template <
    class T, class U,
    enable_if_t<tuple_size<T>::value == tuple_size<U>::value>* = nullptr>
T operator-(const T& a, const U& b) {
  T c(a);
  c -= b;
  return c;
}

template <class T, class U>
T operator*(U r, const T& a) {
  T c(a);
  c *= r;
  return c;
}

template <class T, class E = tuple_element_t<0, T>>
E dot(const T& a, const T& b) {
  E res(0);
  zip_with(a, b, [&](auto&& x, auto&& y) { res += x * y; });
  return res;
}

template <class T, enable_if_t<tuple_size_v<T> == 2>* = nullptr>
auto det(const T& a, const T& b) {
  return get<0>(a) * get<1>(b) - get<1>(a) * get<0>(b);
}

// Returns k s.t. a == kb
// k=inf if b == 0
template <class T>
double factor(const T& a, const T& b) {
  double res = numeric_limits<double>::infinity();
  assert(dot(a, b) == 0);
  zip_with(a, b, [&](auto&&x, auto&& y) {
    if (y) res = x / y;
  });
  return res;
}
Back to top page