This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "la/vec.hpp"
#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;
}