QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#702405 | #9539. Disrupting Communications | ucup-team5234# | AC ✓ | 340ms | 62820kb | C++23 | 77.9kb | 2024-11-02 15:55:32 | 2024-11-02 15:55:33 |
Judging History
answer
#include <algorithm>
#include <array>
#include <cassert>
#include <type_traits>
#include <vector>
#ifdef _MSC_VER
#include <intrin.h>
#endif
#if __cplusplus >= 202002L
#include <bit>
#endif
namespace atcoder {
namespace internal {
#if __cplusplus >= 202002L
using std::bit_ceil;
#else
// @return same with std::bit::bit_ceil
unsigned int bit_ceil(unsigned int n) {
unsigned int x = 1;
while (x < (unsigned int)(n)) x *= 2;
return x;
}
#endif
// @param n `1 <= n`
// @return same with std::bit::countr_zero
int countr_zero(unsigned int n) {
#ifdef _MSC_VER
unsigned long index;
_BitScanForward(&index, n);
return index;
#else
return __builtin_ctz(n);
#endif
}
// @param n `1 <= n`
// @return same with std::bit::countr_zero
constexpr int countr_zero_constexpr(unsigned int n) {
int x = 0;
while (!(n & (1 << x))) x++;
return x;
}
} // namespace internal
} // namespace atcoder
#include <cassert>
#include <numeric>
#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
#endif
#include <utility>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace atcoder {
namespace internal {
// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
x %= m;
if (x < 0) x += m;
return x;
}
// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
unsigned int _m;
unsigned long long im;
// @param m `1 <= m`
explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}
// @return m
unsigned int umod() const { return _m; }
// @param a `0 <= a < m`
// @param b `0 <= b < m`
// @return `a * b % m`
unsigned int mul(unsigned int a, unsigned int b) const {
// [1] m = 1
// a = b = im = 0, so okay
// [2] m >= 2
// im = ceil(2^64 / m)
// -> im * m = 2^64 + r (0 <= r < m)
// let z = a*b = c*m + d (0 <= c, d < m)
// a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
// c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
// ((ab * im) >> 64) == c or c + 1
unsigned long long z = a;
z *= b;
#ifdef _MSC_VER
unsigned long long x;
_umul128(z, im, &x);
#else
unsigned long long x =
(unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
unsigned long long y = x * _m;
return (unsigned int)(z - y + (z < y ? _m : 0));
}
};
// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
if (m == 1) return 0;
unsigned int _m = (unsigned int)(m);
unsigned long long r = 1;
unsigned long long y = safe_mod(x, m);
while (n) {
if (n & 1) r = (r * y) % _m;
y = (y * y) % _m;
n >>= 1;
}
return r;
}
// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
if (n <= 1) return false;
if (n == 2 || n == 7 || n == 61) return true;
if (n % 2 == 0) return false;
long long d = n - 1;
while (d % 2 == 0) d /= 2;
constexpr long long bases[3] = {2, 7, 61};
for (long long a : bases) {
long long t = d;
long long y = pow_mod_constexpr(a, t, n);
while (t != n - 1 && y != 1 && y != n - 1) {
y = y * y % n;
t <<= 1;
}
if (y != n - 1 && t % 2 == 0) {
return false;
}
}
return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);
// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
a = safe_mod(a, b);
if (a == 0) return {b, 0};
// Contracts:
// [1] s - m0 * a = 0 (mod b)
// [2] t - m1 * a = 0 (mod b)
// [3] s * |m1| + t * |m0| <= b
long long s = b, t = a;
long long m0 = 0, m1 = 1;
while (t) {
long long u = s / t;
s -= t * u;
m0 -= m1 * u; // |m1 * u| <= |m1| * s <= b
// [3]:
// (s - t * u) * |m1| + t * |m0 - m1 * u|
// <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
// = s * |m1| + t * |m0| <= b
auto tmp = s;
s = t;
t = tmp;
tmp = m0;
m0 = m1;
m1 = tmp;
}
// by [3]: |m0| <= b/g
// by g != b: |m0| < b/g
if (m0 < 0) m0 += b / s;
return {s, m0};
}
// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
if (m == 2) return 1;
if (m == 167772161) return 3;
if (m == 469762049) return 3;
if (m == 754974721) return 11;
if (m == 998244353) return 3;
int divs[20] = {};
divs[0] = 2;
int cnt = 1;
int x = (m - 1) / 2;
while (x % 2 == 0) x /= 2;
for (int i = 3; (long long)(i)*i <= x; i += 2) {
if (x % i == 0) {
divs[cnt++] = i;
while (x % i == 0) {
x /= i;
}
}
}
if (x > 1) {
divs[cnt++] = x;
}
for (int g = 2;; g++) {
bool ok = true;
for (int i = 0; i < cnt; i++) {
if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
ok = false;
break;
}
}
if (ok) return g;
}
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);
// @param n `n < 2^32`
// @param m `1 <= m < 2^32`
// @return sum_{i=0}^{n-1} floor((ai + b) / m) (mod 2^64)
unsigned long long floor_sum_unsigned(unsigned long long n,
unsigned long long m,
unsigned long long a,
unsigned long long b) {
unsigned long long ans = 0;
while (true) {
if (a >= m) {
ans += n * (n - 1) / 2 * (a / m);
a %= m;
}
if (b >= m) {
ans += n * (b / m);
b %= m;
}
unsigned long long y_max = a * n + b;
if (y_max < m) break;
// y_max < m * (n + 1)
// floor(y_max / m) <= n
n = (unsigned long long)(y_max / m);
b = (unsigned long long)(y_max % m);
std::swap(m, a);
}
return ans;
}
} // namespace internal
} // namespace atcoder
#include <cassert>
#include <numeric>
#include <type_traits>
namespace atcoder {
namespace internal {
#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value ||
std::is_same<T, __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int128 =
typename std::conditional<std::is_same<T, __uint128_t>::value ||
std::is_same<T, unsigned __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using make_unsigned_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value,
__uint128_t,
unsigned __int128>;
template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
is_signed_int128<T>::value ||
is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
std::is_signed<T>::value) ||
is_signed_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int =
typename std::conditional<(is_integral<T>::value &&
std::is_unsigned<T>::value) ||
is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<
is_signed_int128<T>::value,
make_unsigned_int128<T>,
typename std::conditional<std::is_signed<T>::value,
std::make_unsigned<T>,
std::common_type<T>>::type>::type;
#else
template <class T> using is_integral = typename std::is_integral<T>;
template <class T>
using is_signed_int =
typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int =
typename std::conditional<is_integral<T>::value &&
std::is_unsigned<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
std::make_unsigned<T>,
std::common_type<T>>::type;
#endif
template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;
template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;
template <class T> using to_unsigned_t = typename to_unsigned<T>::type;
} // namespace internal
} // namespace atcoder
namespace atcoder {
namespace internal {
struct modint_base {};
struct static_modint_base : modint_base {};
template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;
} // namespace internal
template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
using mint = static_modint;
public:
static constexpr int mod() { return m; }
static mint raw(int v) {
mint x;
x._v = v;
return x;
}
static_modint() : _v(0) {}
template <class T, internal::is_signed_int_t<T>* = nullptr>
static_modint(T v) {
long long x = (long long)(v % (long long)(umod()));
if (x < 0) x += umod();
_v = (unsigned int)(x);
}
template <class T, internal::is_unsigned_int_t<T>* = nullptr>
static_modint(T v) {
_v = (unsigned int)(v % umod());
}
unsigned int val() const { return _v; }
mint& operator++() {
_v++;
if (_v == umod()) _v = 0;
return *this;
}
mint& operator--() {
if (_v == 0) _v = umod();
_v--;
return *this;
}
mint operator++(int) {
mint result = *this;
++*this;
return result;
}
mint operator--(int) {
mint result = *this;
--*this;
return result;
}
mint& operator+=(const mint& rhs) {
_v += rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator-=(const mint& rhs) {
_v -= rhs._v;
if (_v >= umod()) _v += umod();
return *this;
}
mint& operator*=(const mint& rhs) {
unsigned long long z = _v;
z *= rhs._v;
_v = (unsigned int)(z % umod());
return *this;
}
mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
mint operator+() const { return *this; }
mint operator-() const { return mint() - *this; }
mint pow(long long n) const {
assert(0 <= n);
mint x = *this, r = 1;
while (n) {
if (n & 1) r *= x;
x *= x;
n >>= 1;
}
return r;
}
mint inv() const {
if (prime) {
assert(_v);
return pow(umod() - 2);
} else {
auto eg = internal::inv_gcd(_v, m);
assert(eg.first == 1);
return eg.second;
}
}
friend mint operator+(const mint& lhs, const mint& rhs) {
return mint(lhs) += rhs;
}
friend mint operator-(const mint& lhs, const mint& rhs) {
return mint(lhs) -= rhs;
}
friend mint operator*(const mint& lhs, const mint& rhs) {
return mint(lhs) *= rhs;
}
friend mint operator/(const mint& lhs, const mint& rhs) {
return mint(lhs) /= rhs;
}
friend bool operator==(const mint& lhs, const mint& rhs) {
return lhs._v == rhs._v;
}
friend bool operator!=(const mint& lhs, const mint& rhs) {
return lhs._v != rhs._v;
}
private:
unsigned int _v;
static constexpr unsigned int umod() { return m; }
static constexpr bool prime = internal::is_prime<m>;
};
template <int id> struct dynamic_modint : internal::modint_base {
using mint = dynamic_modint;
public:
static int mod() { return (int)(bt.umod()); }
static void set_mod(int m) {
assert(1 <= m);
bt = internal::barrett(m);
}
static mint raw(int v) {
mint x;
x._v = v;
return x;
}
dynamic_modint() : _v(0) {}
template <class T, internal::is_signed_int_t<T>* = nullptr>
dynamic_modint(T v) {
long long x = (long long)(v % (long long)(mod()));
if (x < 0) x += mod();
_v = (unsigned int)(x);
}
template <class T, internal::is_unsigned_int_t<T>* = nullptr>
dynamic_modint(T v) {
_v = (unsigned int)(v % mod());
}
unsigned int val() const { return _v; }
mint& operator++() {
_v++;
if (_v == umod()) _v = 0;
return *this;
}
mint& operator--() {
if (_v == 0) _v = umod();
_v--;
return *this;
}
mint operator++(int) {
mint result = *this;
++*this;
return result;
}
mint operator--(int) {
mint result = *this;
--*this;
return result;
}
mint& operator+=(const mint& rhs) {
_v += rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator-=(const mint& rhs) {
_v += mod() - rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator*=(const mint& rhs) {
_v = bt.mul(_v, rhs._v);
return *this;
}
mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
mint operator+() const { return *this; }
mint operator-() const { return mint() - *this; }
mint pow(long long n) const {
assert(0 <= n);
mint x = *this, r = 1;
while (n) {
if (n & 1) r *= x;
x *= x;
n >>= 1;
}
return r;
}
mint inv() const {
auto eg = internal::inv_gcd(_v, mod());
assert(eg.first == 1);
return eg.second;
}
friend mint operator+(const mint& lhs, const mint& rhs) {
return mint(lhs) += rhs;
}
friend mint operator-(const mint& lhs, const mint& rhs) {
return mint(lhs) -= rhs;
}
friend mint operator*(const mint& lhs, const mint& rhs) {
return mint(lhs) *= rhs;
}
friend mint operator/(const mint& lhs, const mint& rhs) {
return mint(lhs) /= rhs;
}
friend bool operator==(const mint& lhs, const mint& rhs) {
return lhs._v == rhs._v;
}
friend bool operator!=(const mint& lhs, const mint& rhs) {
return lhs._v != rhs._v;
}
private:
unsigned int _v;
static internal::barrett bt;
static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);
using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;
namespace internal {
template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;
template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;
template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};
template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;
} // namespace internal
} // namespace atcoder
namespace atcoder {
namespace internal {
template <class mint,
int g = internal::primitive_root<mint::mod()>,
internal::is_static_modint_t<mint>* = nullptr>
struct fft_info {
static constexpr int rank2 = countr_zero_constexpr(mint::mod() - 1);
std::array<mint, rank2 + 1> root; // root[i]^(2^i) == 1
std::array<mint, rank2 + 1> iroot; // root[i] * iroot[i] == 1
std::array<mint, std::max(0, rank2 - 2 + 1)> rate2;
std::array<mint, std::max(0, rank2 - 2 + 1)> irate2;
std::array<mint, std::max(0, rank2 - 3 + 1)> rate3;
std::array<mint, std::max(0, rank2 - 3 + 1)> irate3;
fft_info() {
root[rank2] = mint(g).pow((mint::mod() - 1) >> rank2);
iroot[rank2] = root[rank2].inv();
for (int i = rank2 - 1; i >= 0; i--) {
root[i] = root[i + 1] * root[i + 1];
iroot[i] = iroot[i + 1] * iroot[i + 1];
}
{
mint prod = 1, iprod = 1;
for (int i = 0; i <= rank2 - 2; i++) {
rate2[i] = root[i + 2] * prod;
irate2[i] = iroot[i + 2] * iprod;
prod *= iroot[i + 2];
iprod *= root[i + 2];
}
}
{
mint prod = 1, iprod = 1;
for (int i = 0; i <= rank2 - 3; i++) {
rate3[i] = root[i + 3] * prod;
irate3[i] = iroot[i + 3] * iprod;
prod *= iroot[i + 3];
iprod *= root[i + 3];
}
}
}
};
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
int n = int(a.size());
int h = internal::countr_zero((unsigned int)n);
static const fft_info<mint> info;
int len = 0; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
while (len < h) {
if (h - len == 1) {
int p = 1 << (h - len - 1);
mint rot = 1;
for (int s = 0; s < (1 << len); s++) {
int offset = s << (h - len);
for (int i = 0; i < p; i++) {
auto l = a[i + offset];
auto r = a[i + offset + p] * rot;
a[i + offset] = l + r;
a[i + offset + p] = l - r;
}
if (s + 1 != (1 << len))
rot *= info.rate2[countr_zero(~(unsigned int)(s))];
}
len++;
} else {
// 4-base
int p = 1 << (h - len - 2);
mint rot = 1, imag = info.root[2];
for (int s = 0; s < (1 << len); s++) {
mint rot2 = rot * rot;
mint rot3 = rot2 * rot;
int offset = s << (h - len);
for (int i = 0; i < p; i++) {
auto mod2 = 1ULL * mint::mod() * mint::mod();
auto a0 = 1ULL * a[i + offset].val();
auto a1 = 1ULL * a[i + offset + p].val() * rot.val();
auto a2 = 1ULL * a[i + offset + 2 * p].val() * rot2.val();
auto a3 = 1ULL * a[i + offset + 3 * p].val() * rot3.val();
auto a1na3imag =
1ULL * mint(a1 + mod2 - a3).val() * imag.val();
auto na2 = mod2 - a2;
a[i + offset] = a0 + a2 + a1 + a3;
a[i + offset + 1 * p] = a0 + a2 + (2 * mod2 - (a1 + a3));
a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
a[i + offset + 3 * p] = a0 + na2 + (mod2 - a1na3imag);
}
if (s + 1 != (1 << len))
rot *= info.rate3[countr_zero(~(unsigned int)(s))];
}
len += 2;
}
}
}
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
int n = int(a.size());
int h = internal::countr_zero((unsigned int)n);
static const fft_info<mint> info;
int len = h; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
while (len) {
if (len == 1) {
int p = 1 << (h - len);
mint irot = 1;
for (int s = 0; s < (1 << (len - 1)); s++) {
int offset = s << (h - len + 1);
for (int i = 0; i < p; i++) {
auto l = a[i + offset];
auto r = a[i + offset + p];
a[i + offset] = l + r;
a[i + offset + p] =
(unsigned long long)(mint::mod() + l.val() - r.val()) *
irot.val();
;
}
if (s + 1 != (1 << (len - 1)))
irot *= info.irate2[countr_zero(~(unsigned int)(s))];
}
len--;
} else {
// 4-base
int p = 1 << (h - len);
mint irot = 1, iimag = info.iroot[2];
for (int s = 0; s < (1 << (len - 2)); s++) {
mint irot2 = irot * irot;
mint irot3 = irot2 * irot;
int offset = s << (h - len + 2);
for (int i = 0; i < p; i++) {
auto a0 = 1ULL * a[i + offset + 0 * p].val();
auto a1 = 1ULL * a[i + offset + 1 * p].val();
auto a2 = 1ULL * a[i + offset + 2 * p].val();
auto a3 = 1ULL * a[i + offset + 3 * p].val();
auto a2na3iimag =
1ULL *
mint((mint::mod() + a2 - a3) * iimag.val()).val();
a[i + offset] = a0 + a1 + a2 + a3;
a[i + offset + 1 * p] =
(a0 + (mint::mod() - a1) + a2na3iimag) * irot.val();
a[i + offset + 2 * p] =
(a0 + a1 + (mint::mod() - a2) + (mint::mod() - a3)) *
irot2.val();
a[i + offset + 3 * p] =
(a0 + (mint::mod() - a1) + (mint::mod() - a2na3iimag)) *
irot3.val();
}
if (s + 1 != (1 << (len - 2)))
irot *= info.irate3[countr_zero(~(unsigned int)(s))];
}
len -= 2;
}
}
}
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_naive(const std::vector<mint>& a,
const std::vector<mint>& b) {
int n = int(a.size()), m = int(b.size());
std::vector<mint> ans(n + m - 1);
if (n < m) {
for (int j = 0; j < m; j++) {
for (int i = 0; i < n; i++) {
ans[i + j] += a[i] * b[j];
}
}
} else {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
ans[i + j] += a[i] * b[j];
}
}
}
return ans;
}
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution_fft(std::vector<mint> a, std::vector<mint> b) {
int n = int(a.size()), m = int(b.size());
int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
a.resize(z);
internal::butterfly(a);
b.resize(z);
internal::butterfly(b);
for (int i = 0; i < z; i++) {
a[i] *= b[i];
}
internal::butterfly_inv(a);
a.resize(n + m - 1);
mint iz = mint(z).inv();
for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
return a;
}
} // namespace internal
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint>&& a, std::vector<mint>&& b) {
int n = int(a.size()), m = int(b.size());
if (!n || !m) return {};
int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
assert((mint::mod() - 1) % z == 0);
if (std::min(n, m) <= 60) return convolution_naive(a, b);
return internal::convolution_fft(a, b);
}
template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(const std::vector<mint>& a,
const std::vector<mint>& b) {
int n = int(a.size()), m = int(b.size());
if (!n || !m) return {};
int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
assert((mint::mod() - 1) % z == 0);
if (std::min(n, m) <= 60) return convolution_naive(a, b);
return internal::convolution_fft(a, b);
}
template <unsigned int mod = 998244353,
class T,
std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
int n = int(a.size()), m = int(b.size());
if (!n || !m) return {};
using mint = static_modint<mod>;
int z = (int)internal::bit_ceil((unsigned int)(n + m - 1));
assert((mint::mod() - 1) % z == 0);
std::vector<mint> a2(n), b2(m);
for (int i = 0; i < n; i++) {
a2[i] = mint(a[i]);
}
for (int i = 0; i < m; i++) {
b2[i] = mint(b[i]);
}
auto c2 = convolution(std::move(a2), std::move(b2));
std::vector<T> c(n + m - 1);
for (int i = 0; i < n + m - 1; i++) {
c[i] = c2[i].val();
}
return c;
}
std::vector<long long> convolution_ll(const std::vector<long long>& a,
const std::vector<long long>& b) {
int n = int(a.size()), m = int(b.size());
if (!n || !m) return {};
static constexpr unsigned long long MOD1 = 754974721; // 2^24
static constexpr unsigned long long MOD2 = 167772161; // 2^25
static constexpr unsigned long long MOD3 = 469762049; // 2^26
static constexpr unsigned long long M2M3 = MOD2 * MOD3;
static constexpr unsigned long long M1M3 = MOD1 * MOD3;
static constexpr unsigned long long M1M2 = MOD1 * MOD2;
static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;
static constexpr unsigned long long i1 =
internal::inv_gcd(MOD2 * MOD3, MOD1).second;
static constexpr unsigned long long i2 =
internal::inv_gcd(MOD1 * MOD3, MOD2).second;
static constexpr unsigned long long i3 =
internal::inv_gcd(MOD1 * MOD2, MOD3).second;
static constexpr int MAX_AB_BIT = 24;
static_assert(MOD1 % (1ull << MAX_AB_BIT) == 1, "MOD1 isn't enough to support an array length of 2^24.");
static_assert(MOD2 % (1ull << MAX_AB_BIT) == 1, "MOD2 isn't enough to support an array length of 2^24.");
static_assert(MOD3 % (1ull << MAX_AB_BIT) == 1, "MOD3 isn't enough to support an array length of 2^24.");
assert(n + m - 1 <= (1 << MAX_AB_BIT));
auto c1 = convolution<MOD1>(a, b);
auto c2 = convolution<MOD2>(a, b);
auto c3 = convolution<MOD3>(a, b);
std::vector<long long> c(n + m - 1);
for (int i = 0; i < n + m - 1; i++) {
unsigned long long x = 0;
x += (c1[i] * i1) % MOD1 * M2M3;
x += (c2[i] * i2) % MOD2 * M1M3;
x += (c3[i] * i3) % MOD3 * M1M2;
// B = 2^63, -B <= x, r(real value) < B
// (x, x - M, x - 2M, or x - 3M) = r (mod 2B)
// r = c1[i] (mod MOD1)
// focus on MOD1
// r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)
// r = x,
// x - M' + (0 or 2B),
// x - 2M' + (0, 2B or 4B),
// x - 3M' + (0, 2B, 4B or 6B) (without mod!)
// (r - x) = 0, (0)
// - M' + (0 or 2B), (1)
// -2M' + (0 or 2B or 4B), (2)
// -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)
// we checked that
// ((1) mod MOD1) mod 5 = 2
// ((2) mod MOD1) mod 5 = 3
// ((3) mod MOD1) mod 5 = 4
long long diff =
c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
if (diff < 0) diff += MOD1;
static constexpr unsigned long long offset[5] = {
0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
x -= offset[diff % 5];
c[i] = x;
}
return c;
}
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <vector>
namespace atcoder {
// Implement (union by size) + (path compression)
// Reference:
// Zvi Galil and Giuseppe F. Italiano,
// Data structures and algorithms for disjoint set union problems
struct dsu {
public:
dsu() : _n(0) {}
explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}
int merge(int a, int b) {
assert(0 <= a && a < _n);
assert(0 <= b && b < _n);
int x = leader(a), y = leader(b);
if (x == y) return x;
if (-parent_or_size[x] < -parent_or_size[y]) std::swap(x, y);
parent_or_size[x] += parent_or_size[y];
parent_or_size[y] = x;
return x;
}
bool same(int a, int b) {
assert(0 <= a && a < _n);
assert(0 <= b && b < _n);
return leader(a) == leader(b);
}
int leader(int a) {
assert(0 <= a && a < _n);
if (parent_or_size[a] < 0) return a;
return parent_or_size[a] = leader(parent_or_size[a]);
}
int size(int a) {
assert(0 <= a && a < _n);
return -parent_or_size[leader(a)];
}
std::vector<std::vector<int>> groups() {
std::vector<int> leader_buf(_n), group_size(_n);
for (int i = 0; i < _n; i++) {
leader_buf[i] = leader(i);
group_size[leader_buf[i]]++;
}
std::vector<std::vector<int>> result(_n);
for (int i = 0; i < _n; i++) {
result[i].reserve(group_size[i]);
}
for (int i = 0; i < _n; i++) {
result[leader_buf[i]].push_back(i);
}
result.erase(
std::remove_if(result.begin(), result.end(),
[&](const std::vector<int>& v) { return v.empty(); }),
result.end());
return result;
}
private:
int _n;
// root node: -1 * component size
// otherwise: parent
std::vector<int> parent_or_size;
};
} // namespace atcoder
#include <cassert>
#include <vector>
namespace atcoder {
// Reference: https://en.wikipedia.org/wiki/Fenwick_tree
template <class T> struct fenwick_tree {
using U = internal::to_unsigned_t<T>;
public:
fenwick_tree() : _n(0) {}
explicit fenwick_tree(int n) : _n(n), data(n) {}
void add(int p, T x) {
assert(0 <= p && p < _n);
p++;
while (p <= _n) {
data[p - 1] += U(x);
p += p & -p;
}
}
T sum(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
return sum(r) - sum(l);
}
private:
int _n;
std::vector<U> data;
U sum(int r) {
U s = 0;
while (r > 0) {
s += data[r - 1];
r -= r & -r;
}
return s;
}
};
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>
namespace atcoder {
#if __cplusplus >= 201703L
template <class S,
auto op,
auto e,
class F,
auto mapping,
auto composition,
auto id>
struct lazy_segtree {
static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
"op must work as S(S, S)");
static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
"e must work as S()");
static_assert(
std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
"mapping must work as F(F, S)");
static_assert(
std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
"compostiion must work as F(F, F)");
static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
"id must work as F()");
#else
template <class S,
S (*op)(S, S),
S (*e)(),
class F,
S (*mapping)(F, S),
F (*composition)(F, F),
F (*id)()>
struct lazy_segtree {
#endif
public:
lazy_segtree() : lazy_segtree(0) {}
explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
size = (int)internal::bit_ceil((unsigned int)(_n));
log = internal::countr_zero((unsigned int)size);
d = std::vector<S>(2 * size, e());
lz = std::vector<F>(size, id());
for (int i = 0; i < _n; i++) d[size + i] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, S x) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
return d[p];
}
S prod(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return e();
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
S sml = e(), smr = e();
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() { return d[1]; }
void apply(int p, F f) {
assert(0 <= p && p < _n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
d[p] = mapping(f, d[p]);
for (int i = 1; i <= log; i++) update(p >> i);
}
void apply(int l, int r, F f) {
assert(0 <= l && l <= r && r <= _n);
if (l == r) return;
l += size;
r += size;
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
{
int l2 = l, r2 = r;
while (l < r) {
if (l & 1) all_apply(l++, f);
if (r & 1) all_apply(--r, f);
l >>= 1;
r >>= 1;
}
l = l2;
r = r2;
}
for (int i = 1; i <= log; i++) {
if (((l >> i) << i) != l) update(l >> i);
if (((r >> i) << i) != r) update((r - 1) >> i);
}
}
template <bool (*g)(S)> int max_right(int l) {
return max_right(l, [](S x) { return g(x); });
}
template <class G> int max_right(int l, G g) {
assert(0 <= l && l <= _n);
assert(g(e()));
if (l == _n) return _n;
l += size;
for (int i = log; i >= 1; i--) push(l >> i);
S sm = e();
do {
while (l % 2 == 0) l >>= 1;
if (!g(op(sm, d[l]))) {
while (l < size) {
push(l);
l = (2 * l);
if (g(op(sm, d[l]))) {
sm = op(sm, d[l]);
l++;
}
}
return l - size;
}
sm = op(sm, d[l]);
l++;
} while ((l & -l) != l);
return _n;
}
template <bool (*g)(S)> int min_left(int r) {
return min_left(r, [](S x) { return g(x); });
}
template <class G> int min_left(int r, G g) {
assert(0 <= r && r <= _n);
assert(g(e()));
if (r == 0) return 0;
r += size;
for (int i = log; i >= 1; i--) push((r - 1) >> i);
S sm = e();
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!g(op(d[r], sm))) {
while (r < size) {
push(r);
r = (2 * r + 1);
if (g(op(d[r], sm))) {
sm = op(d[r], sm);
r--;
}
}
return r + 1 - size;
}
sm = op(d[r], sm);
} while ((r & -r) != r);
return 0;
}
private:
int _n, size, log;
std::vector<S> d;
std::vector<F> lz;
void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
void all_apply(int k, F f) {
d[k] = mapping(f, d[k]);
if (k < size) lz[k] = composition(f, lz[k]);
}
void push(int k) {
all_apply(2 * k, lz[k]);
all_apply(2 * k + 1, lz[k]);
lz[k] = id();
}
};
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <tuple>
#include <vector>
namespace atcoder {
long long pow_mod(long long x, long long n, int m) {
assert(0 <= n && 1 <= m);
if (m == 1) return 0;
internal::barrett bt((unsigned int)(m));
unsigned int r = 1, y = (unsigned int)(internal::safe_mod(x, m));
while (n) {
if (n & 1) r = bt.mul(r, y);
y = bt.mul(y, y);
n >>= 1;
}
return r;
}
long long inv_mod(long long x, long long m) {
assert(1 <= m);
auto z = internal::inv_gcd(x, m);
assert(z.first == 1);
return z.second;
}
// (rem, mod)
std::pair<long long, long long> crt(const std::vector<long long>& r,
const std::vector<long long>& m) {
assert(r.size() == m.size());
int n = int(r.size());
// Contracts: 0 <= r0 < m0
long long r0 = 0, m0 = 1;
for (int i = 0; i < n; i++) {
assert(1 <= m[i]);
long long r1 = internal::safe_mod(r[i], m[i]), m1 = m[i];
if (m0 < m1) {
std::swap(r0, r1);
std::swap(m0, m1);
}
if (m0 % m1 == 0) {
if (r0 % m1 != r1) return {0, 0};
continue;
}
// assume: m0 > m1, lcm(m0, m1) >= 2 * max(m0, m1)
// (r0, m0), (r1, m1) -> (r2, m2 = lcm(m0, m1));
// r2 % m0 = r0
// r2 % m1 = r1
// -> (r0 + x*m0) % m1 = r1
// -> x*u0*g = r1-r0 (mod u1*g) (u0*g = m0, u1*g = m1)
// -> x = (r1 - r0) / g * inv(u0) (mod u1)
// im = inv(u0) (mod u1) (0 <= im < u1)
long long g, im;
std::tie(g, im) = internal::inv_gcd(m0, m1);
long long u1 = (m1 / g);
// |r1 - r0| < (m0 + m1) <= lcm(m0, m1)
if ((r1 - r0) % g) return {0, 0};
// u1 * u1 <= m1 * m1 / g / g <= m0 * m1 / g = lcm(m0, m1)
long long x = (r1 - r0) / g % u1 * im % u1;
// |r0| + |m0 * x|
// < m0 + m0 * (u1 - 1)
// = m0 + m0 * m1 / g - m0
// = lcm(m0, m1)
r0 += x * m0;
m0 *= u1; // -> lcm(m0, m1)
if (r0 < 0) r0 += m0;
}
return {r0, m0};
}
long long floor_sum(long long n, long long m, long long a, long long b) {
assert(0 <= n && n < (1LL << 32));
assert(1 <= m && m < (1LL << 32));
unsigned long long ans = 0;
if (a < 0) {
unsigned long long a2 = internal::safe_mod(a, m);
ans -= 1ULL * n * (n - 1) / 2 * ((a2 - a) / m);
a = a2;
}
if (b < 0) {
unsigned long long b2 = internal::safe_mod(b, m);
ans -= 1ULL * n * ((b2 - b) / m);
b = b2;
}
return ans + internal::floor_sum_unsigned(n, m, a, b);
}
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>
#include <vector>
namespace atcoder {
namespace internal {
template <class T> struct simple_queue {
std::vector<T> payload;
int pos = 0;
void reserve(int n) { payload.reserve(n); }
int size() const { return int(payload.size()) - pos; }
bool empty() const { return pos == int(payload.size()); }
void push(const T& t) { payload.push_back(t); }
T& front() { return payload[pos]; }
void clear() {
payload.clear();
pos = 0;
}
void pop() { pos++; }
};
} // namespace internal
} // namespace atcoder
namespace atcoder {
template <class Cap> struct mf_graph {
public:
mf_graph() : _n(0) {}
explicit mf_graph(int n) : _n(n), g(n) {}
int add_edge(int from, int to, Cap cap) {
assert(0 <= from && from < _n);
assert(0 <= to && to < _n);
assert(0 <= cap);
int m = int(pos.size());
pos.push_back({from, int(g[from].size())});
int from_id = int(g[from].size());
int to_id = int(g[to].size());
if (from == to) to_id++;
g[from].push_back(_edge{to, to_id, cap});
g[to].push_back(_edge{from, from_id, 0});
return m;
}
struct edge {
int from, to;
Cap cap, flow;
};
edge get_edge(int i) {
int m = int(pos.size());
assert(0 <= i && i < m);
auto _e = g[pos[i].first][pos[i].second];
auto _re = g[_e.to][_e.rev];
return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
}
std::vector<edge> edges() {
int m = int(pos.size());
std::vector<edge> result;
for (int i = 0; i < m; i++) {
result.push_back(get_edge(i));
}
return result;
}
void change_edge(int i, Cap new_cap, Cap new_flow) {
int m = int(pos.size());
assert(0 <= i && i < m);
assert(0 <= new_flow && new_flow <= new_cap);
auto& _e = g[pos[i].first][pos[i].second];
auto& _re = g[_e.to][_e.rev];
_e.cap = new_cap - new_flow;
_re.cap = new_flow;
}
Cap flow(int s, int t) {
return flow(s, t, std::numeric_limits<Cap>::max());
}
Cap flow(int s, int t, Cap flow_limit) {
assert(0 <= s && s < _n);
assert(0 <= t && t < _n);
assert(s != t);
std::vector<int> level(_n), iter(_n);
internal::simple_queue<int> que;
auto bfs = [&]() {
std::fill(level.begin(), level.end(), -1);
level[s] = 0;
que.clear();
que.push(s);
while (!que.empty()) {
int v = que.front();
que.pop();
for (auto e : g[v]) {
if (e.cap == 0 || level[e.to] >= 0) continue;
level[e.to] = level[v] + 1;
if (e.to == t) return;
que.push(e.to);
}
}
};
auto dfs = [&](auto self, int v, Cap up) {
if (v == s) return up;
Cap res = 0;
int level_v = level[v];
for (int& i = iter[v]; i < int(g[v].size()); i++) {
_edge& e = g[v][i];
if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
Cap d =
self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
if (d <= 0) continue;
g[v][i].cap += d;
g[e.to][e.rev].cap -= d;
res += d;
if (res == up) return res;
}
level[v] = _n;
return res;
};
Cap flow = 0;
while (flow < flow_limit) {
bfs();
if (level[t] == -1) break;
std::fill(iter.begin(), iter.end(), 0);
Cap f = dfs(dfs, t, flow_limit - flow);
if (!f) break;
flow += f;
}
return flow;
}
std::vector<bool> min_cut(int s) {
std::vector<bool> visited(_n);
internal::simple_queue<int> que;
que.push(s);
while (!que.empty()) {
int p = que.front();
que.pop();
visited[p] = true;
for (auto e : g[p]) {
if (e.cap && !visited[e.to]) {
visited[e.to] = true;
que.push(e.to);
}
}
}
return visited;
}
private:
int _n;
struct _edge {
int to, rev;
Cap cap;
};
std::vector<std::pair<int, int>> pos;
std::vector<std::vector<_edge>> g;
};
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>
#include <algorithm>
#include <utility>
#include <vector>
namespace atcoder {
namespace internal {
template <class E> struct csr {
std::vector<int> start;
std::vector<E> elist;
explicit csr(int n, const std::vector<std::pair<int, E>>& edges)
: start(n + 1), elist(edges.size()) {
for (auto e : edges) {
start[e.first + 1]++;
}
for (int i = 1; i <= n; i++) {
start[i] += start[i - 1];
}
auto counter = start;
for (auto e : edges) {
elist[counter[e.first]++] = e.second;
}
}
};
} // namespace internal
} // namespace atcoder
namespace atcoder {
template <class Cap, class Cost> struct mcf_graph {
public:
mcf_graph() {}
explicit mcf_graph(int n) : _n(n) {}
int add_edge(int from, int to, Cap cap, Cost cost) {
assert(0 <= from && from < _n);
assert(0 <= to && to < _n);
assert(0 <= cap);
assert(0 <= cost);
int m = int(_edges.size());
_edges.push_back({from, to, cap, 0, cost});
return m;
}
struct edge {
int from, to;
Cap cap, flow;
Cost cost;
};
edge get_edge(int i) {
int m = int(_edges.size());
assert(0 <= i && i < m);
return _edges[i];
}
std::vector<edge> edges() { return _edges; }
std::pair<Cap, Cost> flow(int s, int t) {
return flow(s, t, std::numeric_limits<Cap>::max());
}
std::pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {
return slope(s, t, flow_limit).back();
}
std::vector<std::pair<Cap, Cost>> slope(int s, int t) {
return slope(s, t, std::numeric_limits<Cap>::max());
}
std::vector<std::pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {
assert(0 <= s && s < _n);
assert(0 <= t && t < _n);
assert(s != t);
int m = int(_edges.size());
std::vector<int> edge_idx(m);
auto g = [&]() {
std::vector<int> degree(_n), redge_idx(m);
std::vector<std::pair<int, _edge>> elist;
elist.reserve(2 * m);
for (int i = 0; i < m; i++) {
auto e = _edges[i];
edge_idx[i] = degree[e.from]++;
redge_idx[i] = degree[e.to]++;
elist.push_back({e.from, {e.to, -1, e.cap - e.flow, e.cost}});
elist.push_back({e.to, {e.from, -1, e.flow, -e.cost}});
}
auto _g = internal::csr<_edge>(_n, elist);
for (int i = 0; i < m; i++) {
auto e = _edges[i];
edge_idx[i] += _g.start[e.from];
redge_idx[i] += _g.start[e.to];
_g.elist[edge_idx[i]].rev = redge_idx[i];
_g.elist[redge_idx[i]].rev = edge_idx[i];
}
return _g;
}();
auto result = slope(g, s, t, flow_limit);
for (int i = 0; i < m; i++) {
auto e = g.elist[edge_idx[i]];
_edges[i].flow = _edges[i].cap - e.cap;
}
return result;
}
private:
int _n;
std::vector<edge> _edges;
// inside edge
struct _edge {
int to, rev;
Cap cap;
Cost cost;
};
std::vector<std::pair<Cap, Cost>> slope(internal::csr<_edge>& g,
int s,
int t,
Cap flow_limit) {
// variants (C = maxcost):
// -(n-1)C <= dual[s] <= dual[i] <= dual[t] = 0
// reduced cost (= e.cost + dual[e.from] - dual[e.to]) >= 0 for all edge
// dual_dist[i] = (dual[i], dist[i])
std::vector<std::pair<Cost, Cost>> dual_dist(_n);
std::vector<int> prev_e(_n);
std::vector<bool> vis(_n);
struct Q {
Cost key;
int to;
bool operator<(Q r) const { return key > r.key; }
};
std::vector<int> que_min;
std::vector<Q> que;
auto dual_ref = [&]() {
for (int i = 0; i < _n; i++) {
dual_dist[i].second = std::numeric_limits<Cost>::max();
}
std::fill(vis.begin(), vis.end(), false);
que_min.clear();
que.clear();
// que[0..heap_r) was heapified
size_t heap_r = 0;
dual_dist[s].second = 0;
que_min.push_back(s);
while (!que_min.empty() || !que.empty()) {
int v;
if (!que_min.empty()) {
v = que_min.back();
que_min.pop_back();
} else {
while (heap_r < que.size()) {
heap_r++;
std::push_heap(que.begin(), que.begin() + heap_r);
}
v = que.front().to;
std::pop_heap(que.begin(), que.end());
que.pop_back();
heap_r--;
}
if (vis[v]) continue;
vis[v] = true;
if (v == t) break;
// dist[v] = shortest(s, v) + dual[s] - dual[v]
// dist[v] >= 0 (all reduced cost are positive)
// dist[v] <= (n-1)C
Cost dual_v = dual_dist[v].first, dist_v = dual_dist[v].second;
for (int i = g.start[v]; i < g.start[v + 1]; i++) {
auto e = g.elist[i];
if (!e.cap) continue;
// |-dual[e.to] + dual[v]| <= (n-1)C
// cost <= C - -(n-1)C + 0 = nC
Cost cost = e.cost - dual_dist[e.to].first + dual_v;
if (dual_dist[e.to].second - dist_v > cost) {
Cost dist_to = dist_v + cost;
dual_dist[e.to].second = dist_to;
prev_e[e.to] = e.rev;
if (dist_to == dist_v) {
que_min.push_back(e.to);
} else {
que.push_back(Q{dist_to, e.to});
}
}
}
}
if (!vis[t]) {
return false;
}
for (int v = 0; v < _n; v++) {
if (!vis[v]) continue;
// dual[v] = dual[v] - dist[t] + dist[v]
// = dual[v] - (shortest(s, t) + dual[s] - dual[t]) +
// (shortest(s, v) + dual[s] - dual[v]) = - shortest(s,
// t) + dual[t] + shortest(s, v) = shortest(s, v) -
// shortest(s, t) >= 0 - (n-1)C
dual_dist[v].first -= dual_dist[t].second - dual_dist[v].second;
}
return true;
};
Cap flow = 0;
Cost cost = 0, prev_cost_per_flow = -1;
std::vector<std::pair<Cap, Cost>> result = {{Cap(0), Cost(0)}};
while (flow < flow_limit) {
if (!dual_ref()) break;
Cap c = flow_limit - flow;
for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
c = std::min(c, g.elist[g.elist[prev_e[v]].rev].cap);
}
for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
auto& e = g.elist[prev_e[v]];
e.cap += c;
g.elist[e.rev].cap -= c;
}
Cost d = -dual_dist[s].first;
flow += c;
cost += c * d;
if (prev_cost_per_flow == d) {
result.pop_back();
}
result.push_back({flow, cost});
prev_cost_per_flow = d;
}
return result;
}
};
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <vector>
#include <algorithm>
#include <utility>
#include <vector>
namespace atcoder {
namespace internal {
// Reference:
// R. Tarjan,
// Depth-First Search and Linear Graph Algorithms
struct scc_graph {
public:
explicit scc_graph(int n) : _n(n) {}
int num_vertices() { return _n; }
void add_edge(int from, int to) { edges.push_back({from, {to}}); }
// @return pair of (# of scc, scc id)
std::pair<int, std::vector<int>> scc_ids() {
auto g = csr<edge>(_n, edges);
int now_ord = 0, group_num = 0;
std::vector<int> visited, low(_n), ord(_n, -1), ids(_n);
visited.reserve(_n);
auto dfs = [&](auto self, int v) -> void {
low[v] = ord[v] = now_ord++;
visited.push_back(v);
for (int i = g.start[v]; i < g.start[v + 1]; i++) {
auto to = g.elist[i].to;
if (ord[to] == -1) {
self(self, to);
low[v] = std::min(low[v], low[to]);
} else {
low[v] = std::min(low[v], ord[to]);
}
}
if (low[v] == ord[v]) {
while (true) {
int u = visited.back();
visited.pop_back();
ord[u] = _n;
ids[u] = group_num;
if (u == v) break;
}
group_num++;
}
};
for (int i = 0; i < _n; i++) {
if (ord[i] == -1) dfs(dfs, i);
}
for (auto& x : ids) {
x = group_num - 1 - x;
}
return {group_num, ids};
}
std::vector<std::vector<int>> scc() {
auto ids = scc_ids();
int group_num = ids.first;
std::vector<int> counts(group_num);
for (auto x : ids.second) counts[x]++;
std::vector<std::vector<int>> groups(ids.first);
for (int i = 0; i < group_num; i++) {
groups[i].reserve(counts[i]);
}
for (int i = 0; i < _n; i++) {
groups[ids.second[i]].push_back(i);
}
return groups;
}
private:
int _n;
struct edge {
int to;
};
std::vector<std::pair<int, edge>> edges;
};
} // namespace internal
} // namespace atcoder
namespace atcoder {
struct scc_graph {
public:
scc_graph() : internal(0) {}
explicit scc_graph(int n) : internal(n) {}
void add_edge(int from, int to) {
int n = internal.num_vertices();
assert(0 <= from && from < n);
assert(0 <= to && to < n);
internal.add_edge(from, to);
}
std::vector<std::vector<int>> scc() { return internal.scc(); }
private:
internal::scc_graph internal;
};
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>
namespace atcoder {
#if __cplusplus >= 201703L
template <class S, auto op, auto e> struct segtree {
static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
"op must work as S(S, S)");
static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
"e must work as S()");
#else
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
#endif
public:
segtree() : segtree(0) {}
explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
size = (int)internal::bit_ceil((unsigned int)(_n));
log = internal::countr_zero((unsigned int)size);
d = std::vector<S>(2 * size, e());
for (int i = 0; i < _n; i++) d[size + i] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, S x) {
assert(0 <= p && p < _n);
p += size;
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) const {
assert(0 <= p && p < _n);
return d[p + size];
}
S prod(int l, int r) const {
assert(0 <= l && l <= r && r <= _n);
S sml = e(), smr = e();
l += size;
r += size;
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() const { return d[1]; }
template <bool (*f)(S)> int max_right(int l) const {
return max_right(l, [](S x) { return f(x); });
}
template <class F> int max_right(int l, F f) const {
assert(0 <= l && l <= _n);
assert(f(e()));
if (l == _n) return _n;
l += size;
S sm = e();
do {
while (l % 2 == 0) l >>= 1;
if (!f(op(sm, d[l]))) {
while (l < size) {
l = (2 * l);
if (f(op(sm, d[l]))) {
sm = op(sm, d[l]);
l++;
}
}
return l - size;
}
sm = op(sm, d[l]);
l++;
} while ((l & -l) != l);
return _n;
}
template <bool (*f)(S)> int min_left(int r) const {
return min_left(r, [](S x) { return f(x); });
}
template <class F> int min_left(int r, F f) const {
assert(0 <= r && r <= _n);
assert(f(e()));
if (r == 0) return 0;
r += size;
S sm = e();
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!f(op(d[r], sm))) {
while (r < size) {
r = (2 * r + 1);
if (f(op(d[r], sm))) {
sm = op(d[r], sm);
r--;
}
}
return r + 1 - size;
}
sm = op(d[r], sm);
} while ((r & -r) != r);
return 0;
}
private:
int _n, size, log;
std::vector<S> d;
void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
} // namespace atcoder
#include <algorithm>
#include <cassert>
#include <numeric>
#include <string>
#include <vector>
namespace atcoder {
namespace internal {
std::vector<int> sa_naive(const std::vector<int>& s) {
int n = int(s.size());
std::vector<int> sa(n);
std::iota(sa.begin(), sa.end(), 0);
std::sort(sa.begin(), sa.end(), [&](int l, int r) {
if (l == r) return false;
while (l < n && r < n) {
if (s[l] != s[r]) return s[l] < s[r];
l++;
r++;
}
return l == n;
});
return sa;
}
std::vector<int> sa_doubling(const std::vector<int>& s) {
int n = int(s.size());
std::vector<int> sa(n), rnk = s, tmp(n);
std::iota(sa.begin(), sa.end(), 0);
for (int k = 1; k < n; k *= 2) {
auto cmp = [&](int x, int y) {
if (rnk[x] != rnk[y]) return rnk[x] < rnk[y];
int rx = x + k < n ? rnk[x + k] : -1;
int ry = y + k < n ? rnk[y + k] : -1;
return rx < ry;
};
std::sort(sa.begin(), sa.end(), cmp);
tmp[sa[0]] = 0;
for (int i = 1; i < n; i++) {
tmp[sa[i]] = tmp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) ? 1 : 0);
}
std::swap(tmp, rnk);
}
return sa;
}
// SA-IS, linear-time suffix array construction
// Reference:
// G. Nong, S. Zhang, and W. H. Chan,
// Two Efficient Algorithms for Linear Time Suffix Array Construction
template <int THRESHOLD_NAIVE = 10, int THRESHOLD_DOUBLING = 40>
std::vector<int> sa_is(const std::vector<int>& s, int upper) {
int n = int(s.size());
if (n == 0) return {};
if (n == 1) return {0};
if (n == 2) {
if (s[0] < s[1]) {
return {0, 1};
} else {
return {1, 0};
}
}
if (n < THRESHOLD_NAIVE) {
return sa_naive(s);
}
if (n < THRESHOLD_DOUBLING) {
return sa_doubling(s);
}
std::vector<int> sa(n);
std::vector<bool> ls(n);
for (int i = n - 2; i >= 0; i--) {
ls[i] = (s[i] == s[i + 1]) ? ls[i + 1] : (s[i] < s[i + 1]);
}
std::vector<int> sum_l(upper + 1), sum_s(upper + 1);
for (int i = 0; i < n; i++) {
if (!ls[i]) {
sum_s[s[i]]++;
} else {
sum_l[s[i] + 1]++;
}
}
for (int i = 0; i <= upper; i++) {
sum_s[i] += sum_l[i];
if (i < upper) sum_l[i + 1] += sum_s[i];
}
auto induce = [&](const std::vector<int>& lms) {
std::fill(sa.begin(), sa.end(), -1);
std::vector<int> buf(upper + 1);
std::copy(sum_s.begin(), sum_s.end(), buf.begin());
for (auto d : lms) {
if (d == n) continue;
sa[buf[s[d]]++] = d;
}
std::copy(sum_l.begin(), sum_l.end(), buf.begin());
sa[buf[s[n - 1]]++] = n - 1;
for (int i = 0; i < n; i++) {
int v = sa[i];
if (v >= 1 && !ls[v - 1]) {
sa[buf[s[v - 1]]++] = v - 1;
}
}
std::copy(sum_l.begin(), sum_l.end(), buf.begin());
for (int i = n - 1; i >= 0; i--) {
int v = sa[i];
if (v >= 1 && ls[v - 1]) {
sa[--buf[s[v - 1] + 1]] = v - 1;
}
}
};
std::vector<int> lms_map(n + 1, -1);
int m = 0;
for (int i = 1; i < n; i++) {
if (!ls[i - 1] && ls[i]) {
lms_map[i] = m++;
}
}
std::vector<int> lms;
lms.reserve(m);
for (int i = 1; i < n; i++) {
if (!ls[i - 1] && ls[i]) {
lms.push_back(i);
}
}
induce(lms);
if (m) {
std::vector<int> sorted_lms;
sorted_lms.reserve(m);
for (int v : sa) {
if (lms_map[v] != -1) sorted_lms.push_back(v);
}
std::vector<int> rec_s(m);
int rec_upper = 0;
rec_s[lms_map[sorted_lms[0]]] = 0;
for (int i = 1; i < m; i++) {
int l = sorted_lms[i - 1], r = sorted_lms[i];
int end_l = (lms_map[l] + 1 < m) ? lms[lms_map[l] + 1] : n;
int end_r = (lms_map[r] + 1 < m) ? lms[lms_map[r] + 1] : n;
bool same = true;
if (end_l - l != end_r - r) {
same = false;
} else {
while (l < end_l) {
if (s[l] != s[r]) {
break;
}
l++;
r++;
}
if (l == n || s[l] != s[r]) same = false;
}
if (!same) rec_upper++;
rec_s[lms_map[sorted_lms[i]]] = rec_upper;
}
auto rec_sa =
sa_is<THRESHOLD_NAIVE, THRESHOLD_DOUBLING>(rec_s, rec_upper);
for (int i = 0; i < m; i++) {
sorted_lms[i] = lms[rec_sa[i]];
}
induce(sorted_lms);
}
return sa;
}
} // namespace internal
std::vector<int> suffix_array(const std::vector<int>& s, int upper) {
assert(0 <= upper);
for (int d : s) {
assert(0 <= d && d <= upper);
}
auto sa = internal::sa_is(s, upper);
return sa;
}
template <class T> std::vector<int> suffix_array(const std::vector<T>& s) {
int n = int(s.size());
std::vector<int> idx(n);
iota(idx.begin(), idx.end(), 0);
sort(idx.begin(), idx.end(), [&](int l, int r) { return s[l] < s[r]; });
std::vector<int> s2(n);
int now = 0;
for (int i = 0; i < n; i++) {
if (i && s[idx[i - 1]] != s[idx[i]]) now++;
s2[idx[i]] = now;
}
return internal::sa_is(s2, now);
}
std::vector<int> suffix_array(const std::string& s) {
int n = int(s.size());
std::vector<int> s2(n);
for (int i = 0; i < n; i++) {
s2[i] = s[i];
}
return internal::sa_is(s2, 255);
}
// Reference:
// T. Kasai, G. Lee, H. Arimura, S. Arikawa, and K. Park,
// Linear-Time Longest-Common-Prefix Computation in Suffix Arrays and Its
// Applications
template <class T>
std::vector<int> lcp_array(const std::vector<T>& s,
const std::vector<int>& sa) {
int n = int(s.size());
assert(n >= 1);
std::vector<int> rnk(n);
for (int i = 0; i < n; i++) {
rnk[sa[i]] = i;
}
std::vector<int> lcp(n - 1);
int h = 0;
for (int i = 0; i < n; i++) {
if (h > 0) h--;
if (rnk[i] == 0) continue;
int j = sa[rnk[i] - 1];
for (; j + h < n && i + h < n; h++) {
if (s[j + h] != s[i + h]) break;
}
lcp[rnk[i] - 1] = h;
}
return lcp;
}
std::vector<int> lcp_array(const std::string& s, const std::vector<int>& sa) {
int n = int(s.size());
std::vector<int> s2(n);
for (int i = 0; i < n; i++) {
s2[i] = s[i];
}
return lcp_array(s2, sa);
}
// Reference:
// D. Gusfield,
// Algorithms on Strings, Trees, and Sequences: Computer Science and
// Computational Biology
template <class T> std::vector<int> z_algorithm(const std::vector<T>& s) {
int n = int(s.size());
if (n == 0) return {};
std::vector<int> z(n);
z[0] = 0;
for (int i = 1, j = 0; i < n; i++) {
int& k = z[i];
k = (j + z[j] <= i) ? 0 : std::min(j + z[j] - i, z[i - j]);
while (i + k < n && s[k] == s[i + k]) k++;
if (j + z[j] < i + z[i]) j = i;
}
z[0] = n;
return z;
}
std::vector<int> z_algorithm(const std::string& s) {
int n = int(s.size());
std::vector<int> s2(n);
for (int i = 0; i < n; i++) {
s2[i] = s[i];
}
return z_algorithm(s2);
}
} // namespace atcoder
#include <cassert>
#include <vector>
namespace atcoder {
// Reference:
// B. Aspvall, M. Plass, and R. Tarjan,
// A Linear-Time Algorithm for Testing the Truth of Certain Quantified Boolean
// Formulas
struct two_sat {
public:
two_sat() : _n(0), scc(0) {}
explicit two_sat(int n) : _n(n), _answer(n), scc(2 * n) {}
void add_clause(int i, bool f, int j, bool g) {
assert(0 <= i && i < _n);
assert(0 <= j && j < _n);
scc.add_edge(2 * i + (f ? 0 : 1), 2 * j + (g ? 1 : 0));
scc.add_edge(2 * j + (g ? 0 : 1), 2 * i + (f ? 1 : 0));
}
bool satisfiable() {
auto id = scc.scc_ids().second;
for (int i = 0; i < _n; i++) {
if (id[2 * i] == id[2 * i + 1]) return false;
_answer[i] = id[2 * i] < id[2 * i + 1];
}
return true;
}
std::vector<bool> answer() { return _answer; }
private:
int _n;
std::vector<bool> _answer;
internal::scc_graph scc;
};
} // namespace atcoder
#include <bits/stdc++.h>
using namespace std;
#define SZ(x) (int) (x).size()
#define REP(i, n) for(int i = 0; i < (n); i++)
#define FOR(i, a, b) for(auto i = (a); i < (b); i++)
#define For(i, a, b, c) \
for(auto i = (a); i != (b); i += (c))
#define REPR(i, n) for(auto i = (n) - 1; i >= 0; i--)
#define ALL(s) (s).begin(), (s).end()
#define so(V) sort(ALL(V))
#define rev(V) reverse(ALL(V))
#define uni(v) v.erase(unique(ALL(v)), (v).end())
#define eb emplace_back
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> PI;
typedef pair<ll, ll> PL;
const double EPS = 1e-6;
const int MOD = 1e9 + 7;
const int INF = (1 << 30);
const ll LINF = 1e18;
const double math_PI = acos(-1);
template<typename T>
vector<T> make_v(size_t a) {
return vector<T>(a);
}
template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
return vector<decltype(make_v<T>(ts...))>(
a, make_v<T>(ts...));
}
template<typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(
T &t, const V &v) {
t = v;
}
template<typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(
T &t, const V &v) {
for(auto &e: t) fill_v(e, v);
}
template<class T>
bool chmax(T &a, const T &b) {
if(a < b) {
a = b;
return true;
}
return false;
}
template<class T>
bool chmin(T &a, const T &b) {
if(a > b) {
a = b;
return true;
}
return false;
}
template<typename S, typename T>
istream &operator>>(istream &is, pair<S, T> &p) {
cin >> p.first >> p.second;
return is;
}
template<typename T>
istream &operator>>(istream &is, vector<T> &vec) {
for(T &x: vec) is >> x;
return is;
}
template<typename T>
string join(vector<T> &vec, string splitter) {
stringstream ss;
REP(i, SZ(vec)) {
if(i != 0) ss << splitter;
ss << vec[i];
}
return ss.str();
}
template<typename T>
ostream &operator<<(ostream &os, vector<T> &vec) {
os << join(vec, " ");
return os;
}
#ifdef LOCAL
#include "./cpp-dump/dump.hpp"
#include "./cpp-dump/mytypes.hpp"
#define dump(...) cpp_dump(__VA_ARGS__)
namespace cp = cpp_dump;
#else
#define dump(...)
#define preprocess(...)
#define CPP_DUMP_SET_OPTION(...)
#define CPP_DUMP_DEFINE_EXPORT_OBJECT(...)
#define CPP_DUMP_DEFINE_EXPORT_ENUM(...)
#define CPP_DUMP_DEFINE_DANGEROUS_EXPORT_OBJECT(...)
#endif
template<class T = ll>
struct Edge {
public:
int from, to;
T cost;
Edge() {
}
Edge(int _from, int _to, T _cost) {
from = _from;
to = _to;
cost = _cost;
}
};
template<class T = ll>
using Edges = vector<Edge<T>>;
template<class T = ll>
using Graph = vector<Edges<T>>;
class HLdecomposition {
private:
int V;
vector<vector<int>> G;
vector<int> stsize, parent, pathtop, in, out;
int root;
bool built_flag;
void BuildStsize(int u, int p) {
stsize[u] = 1, parent[u] = p;
for(int& v: G[u]) {
if(v == p) {
if(v == G[u].back())
break;
else
swap(v, G[u].back());
}
BuildStsize(v, u);
stsize[u] += stsize[v];
if(stsize[v] > stsize[G[u][0]]) {
swap(v, G[u][0]);
}
}
}
void BuildPath(int u, int p, int& tm) {
in[u] = tm++;
for(int v: G[u]) {
if(v == p) continue;
pathtop[v] = (v == G[u][0] ? pathtop[u] : v);
BuildPath(v, u, tm);
}
out[u] = tm;
}
public:
void add_edge(int u, int v) {
G[u].push_back(v), G[v].push_back(u);
}
void build(int _root = 0) {
root = _root;
built_flag = true;
int tm = 0;
BuildStsize(root, -1);
pathtop[root] = root;
BuildPath(root, -1, tm);
}
inline int index(int a) {
return in[a];
}
int lca(int a, int b) {
int pa = pathtop[a], pb = pathtop[b];
while(pathtop[a] != pathtop[b]) {
if(in[pa] > in[pb]) {
a = parent[pa], pa = pathtop[a];
} else {
b = parent[pb], pb = pathtop[b];
}
}
if(in[a] > in[b]) swap(a, b);
return a;
}
PI subtree_query(int a) {
assert(
built_flag
&& "You must call hld.build() before call query function");
return { in[a], out[a] };
}
vector<tuple<int, int, bool>> path_query(int from,
int to) {
assert(
built_flag
&& "You must call hld.build() before call query function");
int pf = pathtop[from], pt = pathtop[to];
using T = tuple<int, int, bool>;
deque<T> front, back;
while(pathtop[from] != pathtop[to]) {
if(in[pf] > in[pt]) {
front.emplace_back(in[pf], in[from] + 1,
true);
from = parent[pf], pf = pathtop[from];
} else {
back.emplace_front(in[pt], in[to] + 1,
false);
to = parent[pt], pt = pathtop[to];
}
}
if(in[from] > in[to]) {
front.emplace_back(in[to], in[from] + 1, true);
} else {
front.emplace_back(in[from], in[to] + 1, false);
}
vector<T> ret;
while(!front.empty()) {
ret.push_back(front.front());
front.pop_front();
}
while(!back.empty()) {
ret.push_back(back.front());
back.pop_front();
}
return ret;
}
HLdecomposition(int node_size)
: V(node_size),
G(V),
stsize(V, 0),
parent(V, -1),
pathtop(V, -1),
in(V, -1),
out(V, -1),
built_flag(false) {
}
};
template<typename T>
struct RangeSum {
private:
vector<T> V;
int N = -1;
public:
RangeSum(vector<T> &v) {
N = SZ(v);
V = vector<T>(N + 1);
V[0] = T(0);
REP(i, N) {
V[i + 1] = v[i] + V[i];
}
}
T sum(int l, int r) {
chmax(l, 0);
chmin(r, N);
chmax(r, l);
return V[r] - V[l];
}
};
template<typename T>
struct RangeSum2D {
private:
vector<vector<T>> V;
int H = -1;
int W = -1;
public:
RangeSum2D(vector<vector<T>> &v) {
H = SZ(v);
W = SZ(v[0]);
V = vector<vector<T>>(H, vector<T>(W));
REP(i, H) {
REP(j, W) {
V[i][j] += v[i][j];
if(i != 0) V[i][j] += V[i - 1][j];
if(j != 0) V[i][j] += V[i][j - 1];
if(i != 0 && j != 0)
V[i][j] -= V[i - 1][j - 1];
}
}
}
T sum(int y1, int x1, int y2, int x2) {
T ret = V[y2][x2];
if(y1 != 0) ret -= V[y1 - 1][x2];
if(x1 != 0) ret -= V[y2][x1 - 1];
if(y1 != 0 && x1 != 0) ret += V[y1 - 1][x1 - 1];
return ret;
}
};
template <typename Data, typename Cost = ll> struct Rerooting {
vector<Data> dp, memo;
Graph<> G;
int N = -1;
using F1 = function<Data(Data, Data)>;
using F2 = function<Data(Data, Edge<Cost>)>;
F1 merge;
F2 apply;
Data e, leaf;
map<ll, Data> hash;
bool calc_contribution;
Rerooting(int n, F1 merge, F2 apply, Data e, Data leaf,
bool calc_contribution = false)
: N(n), merge(merge), apply(apply), e(e), leaf(leaf),
calc_contribution(calc_contribution) {
G = Graph<Cost>(n);
}
void add_edge(int u, int v, Cost cost) {
G[u].eb(u, v, cost);
G[v].eb(v, u, cost);
}
void add_edge(Edge<Cost> edge) {
assert(0 <= edge.from && edge.from < N && 0 <= edge.to && edge.to < N);
G[edge.from].push_back(edge);
}
vector<Data> build() {
memo = vector<Data>(SZ(G), e);
dp = vector<Data>(SZ(G));
dfs1(0);
dfs2(0, e);
return dp;
}
Data getContribution(int p, int c) {
assert(calc_contribution &&
"Enable this function by setting calc_contribution = true");
if (hash.count(p * N + c) == 0) {
return e;
} else {
return hash[p * N + c];
}
}
private:
void dfs1(int cur, int pre = -1) {
bool isLeaf = true;
for (Edge<Cost> edge : G[cur]) {
if (edge.to == pre)
continue;
dfs1(edge.to, cur);
isLeaf = false;
memo[cur] =
merge(memo[cur], apply(memo[edge.to], Edge(edge.to, cur, edge.cost)));
}
if (isLeaf)
memo[cur] = leaf;
}
void dfs2(int cur, const Data val, int pre = -1) {
vector<Data> ds{val};
if (calc_contribution && pre != -1) {
hash[cur * N + pre] = val;
}
for (auto edge : G[cur]) {
if (edge.to == pre)
continue;
ds.push_back(apply(memo[edge.to], Edge<Cost>(edge.to, cur, edge.cost)));
if (calc_contribution) {
hash[cur * N + edge.to] =
apply(memo[edge.to], Edge<Cost>(edge.to, cur, edge.cost));
}
}
int N = SZ(ds);
vector<Data> dp_left(N + 1, e), dp_right(N + 1, e);
REP(i, N) dp_left[i + 1] = merge(dp_left[i], ds[i]);
REPR(i, N)
dp_right[i] = merge(dp_right[i + 1], ds[i]);
dp[cur] = dp_left[N];
int ind = 1; // 親以外の頂点にインデックスをつける
for (auto edge : G[cur]) {
if (edge.to == pre)
continue;
Data sub = merge(dp_left[ind], dp_right[ind + 1]);
dfs2(edge.to, apply(sub, Edge<Cost>(cur, edge.to, edge.cost)), cur);
ind++;
}
}
};
using namespace atcoder;
using mint = modint998244353;
void solve() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int N, Q;
cin >> N >> Q;
vector<mint> ans(N);
vi P(N);
vvi G(N);
auto merge = [](mint a, mint b) -> mint {
return a * b;
};
auto apply = [](mint a, Edge<> e) -> mint {
return a + 1;
};
Rerooting<mint> rr(N, merge, apply, 1, 1);
HLdecomposition hld(N);
FOR(i, 1, N) {
cin >> P[i];
P[i]--;
G[P[i]].push_back(i);
rr.add_edge(P[i], i, 1);
hld.add_edge(i, P[i]);
}
auto dfs = [&](auto f, int cur) -> mint {
mint c = 1;
for(auto to: G[cur]) {
c *= f(f, to);
}
ans[cur] = c;
return c + 1;
};
dfs(dfs, 0);
vector<mint> ans2 = rr.build();
REP(i, N) {
dump(i, ans[i].val(), ans2[i].val());
}
hld.build();
vector<mint> V(N);
REP(i, N) {
V[hld.index(i)] = ans[i];
}
RangeSum<mint> RS(V);
while(Q--) {
int u, v;
cin >> u >> v;
u--;
v--;
int p = hld.lca(u, v);
mint A = 0;
for(auto [l, r, b]: hld.path_query(u, v)) {
A += RS.sum(l, r);
}
A -= ans[p];
A += ans2[p];
cout << A.val() << endl;
}
return;
}
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int T;
cin >> T;
while(T--) {
solve();
}
return 0;
}
这程序好像有点Bug,我给组数据试试?
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 3936kb
input:
2 3 2 1 1 2 3 1 2 5 3 1 1 2 2 4 5 2 4 2 3
output:
6 5 14 13 15
result:
ok 5 lines
Test #2:
score: 0
Accepted
time: 260ms
memory: 3752kb
input:
3000 98 100 1 2 1 3 5 3 2 5 5 4 3 7 12 10 12 8 10 4 4 3 10 14 11 11 22 23 14 20 29 1 18 7 12 29 20 29 12 21 6 20 3 25 7 21 16 44 38 44 7 11 5 24 34 24 41 48 56 58 56 3 26 55 62 33 9 38 63 39 3 67 14 24 60 35 1 22 74 36 57 61 55 46 44 12 16 60 44 50 22 58 78 15 57 57 75 88 15 43 28 67 66 3 39 6 19 84...
output:
964062690 949799024 949777463 964050185 119859605 949794873 949799267 964064991 836980963 964045750 964065023 959849545 536098301 964045791 964064966 964046253 964052677 949782329 964050627 949794848 188617843 964065041 2617316 949782330 964046253 536098346 949777935 964052584 949777939 964046254 94...
result:
ok 300000 lines
Test #3:
score: 0
Accepted
time: 293ms
memory: 3948kb
input:
300 998 1000 1 2 1 3 3 2 2 8 5 2 8 8 12 3 13 3 7 8 16 14 10 22 10 1 24 17 16 1 16 21 2 23 2 1 20 11 1 1 22 19 5 15 10 37 15 39 13 16 33 37 37 36 37 16 3 45 10 28 14 4 16 17 55 6 6 5 31 67 51 35 47 48 10 16 75 21 45 71 28 64 39 9 37 5 65 79 28 84 29 79 21 50 21 16 93 72 58 35 30 14 86 90 60 65 33 47 ...
output:
327306708 121504060 970333956 71256467 492200713 164920447 56359491 54857868 62271655 175858304 373532115 138628785 54854112 616763633 41337286 837501264 861536431 572242958 417784906 22152900 460075855 89587278 985881197 291627546 96610921 437457168 101307362 180803897 373532108 80109336 837492247 ...
result:
ok 300000 lines
Test #4:
score: 0
Accepted
time: 316ms
memory: 59084kb
input:
3 100000 100000 1 1 2 4 2 4 6 5 1 8 9 7 12 10 7 12 10 4 9 7 6 22 10 5 18 3 8 18 5 20 12 26 10 11 14 5 28 29 33 12 5 10 30 21 36 24 1 26 39 29 2 42 40 33 41 39 23 2 50 11 47 61 61 52 3 27 65 4 24 1 15 41 68 5 62 1 44 60 44 79 68 6 53 72 21 58 66 24 54 78 29 39 75 74 13 52 71 35 40 85 47 19 60 44 101 ...
output:
174648911 988966670 586060443 352691812 610467698 718056854 353397034 944134980 945506609 743772159 17398768 898225958 509929535 581516662 124983919 679181027 890516256 792976265 81256963 846568565 990778256 394490295 307247131 281874314 78565559 438162317 218440246 677940950 608561943 237178689 748...
result:
ok 300000 lines
Test #5:
score: 0
Accepted
time: 340ms
memory: 59020kb
input:
3 100000 100000 1 2 3 2 2 3 4 3 7 6 10 8 6 4 3 6 5 8 3 17 2 7 1 1 17 3 4 11 25 26 5 7 2 20 2 32 35 11 9 39 16 42 26 43 29 22 35 18 3 34 45 19 27 3 41 27 10 14 4 4 45 53 35 49 57 37 24 43 68 6 44 5 15 12 62 22 11 26 37 41 8 73 56 76 78 9 46 14 81 67 49 12 74 15 16 69 86 48 47 77 58 77 87 54 79 80 99 ...
output:
761112418 717651384 861477152 134730845 623546487 488508714 852403783 522543884 880846196 809656417 876270841 575462796 111884802 845956357 990889899 222833220 7564761 917539269 355409810 261089607 166264493 612109684 526575279 410009284 848925228 885468503 90907188 969960703 663719627 309794696 503...
result:
ok 300000 lines
Test #6:
score: 0
Accepted
time: 176ms
memory: 24968kb
input:
3 100000 100000 1 2 1 2 3 5 1 4 2 6 10 3 10 6 13 14 4 18 13 4 21 19 9 16 14 5 13 15 10 29 11 4 33 31 25 15 19 32 12 17 22 24 35 38 3 1 46 28 16 8 13 5 46 44 25 49 37 30 47 37 10 56 32 29 36 7 13 47 11 2 24 6 51 65 36 52 15 74 62 65 25 34 35 61 12 4 20 81 64 39 21 79 90 29 68 30 7 34 60 1 1 1 1 1 1 1...
output:
47613014 867989885 314355471 515168737 161160818 552527 328577529 705173752 262933227 431743363 481168259 545043565 319743713 655278418 20733052 900938971 104104163 575553196 635937653 545910595 298966873 864807486 817091004 10697715 66840685 327639210 80580410 489368876 303238352 545043565 26533356...
result:
ok 300000 lines
Test #7:
score: 0
Accepted
time: 324ms
memory: 25352kb
input:
10000 10 10 1 2 2 4 4 3 4 7 9 5 4 6 7 1 9 9 5 2 2 2 1 4 5 5 5 4 6 7 6 10 10 1 1 2 4 3 4 7 5 6 10 7 7 5 10 2 10 1 4 6 1 4 1 9 8 9 4 2 10 5 9 9 1 2 1 4 2 5 2 5 5 6 9 4 4 4 3 4 6 9 8 2 7 9 9 4 1 3 10 10 1 1 2 4 4 2 7 6 1 2 10 3 10 2 6 8 3 4 8 5 6 8 5 3 6 6 10 4 7 9 9 1 2 1 3 5 2 5 2 7 8 9 6 7 2 2 3 2 6...
output:
89 106 100 108 90 91 89 45 89 106 71 58 60 50 68 63 66 60 59 71 72 55 50 68 73 57 46 55 63 110 90 113 113 114 99 115 118 118 113 83 83 73 77 82 57 82 57 83 90 91 92 92 91 59 91 93 88 66 79 69 80 72 66 66 63 33 171 169 169 170 106 160 159 157 168 169 56 91 23 95 86 80 87 91 92 89 40 34 41 37 31 37 33...
result:
ok 290206 lines
Test #8:
score: 0
Accepted
time: 224ms
memory: 62524kb
input:
10000 9 9 1 2 2 4 2 5 1 7 1 2 4 7 5 6 5 7 7 4 8 5 5 8 7 4 8 5 10 10 1 2 1 1 5 2 1 7 3 5 3 5 9 5 6 10 9 3 5 2 6 6 6 8 10 7 7 6 6 10 10 1 1 2 4 5 1 2 3 7 3 5 4 7 5 9 7 8 1 3 5 8 1 9 6 9 8 6 7 10 10 10 1 2 3 1 1 1 3 3 2 1 1 3 10 10 6 4 10 4 10 3 2 8 9 6 8 6 3 8 9 10 10 1 2 1 3 4 6 3 7 5 10 6 10 7 3 6 5...
output:
62 57 68 44 57 70 70 57 70 133 134 83 123 133 132 42 133 80 42 96 94 97 92 83 86 84 98 87 57 152 171 172 172 172 170 154 180 179 154 63 65 60 30 46 49 42 63 62 54 97 110 98 114 114 115 98 110 112 112 170 171 170 158 160 170 171 79 169 160 74 74 77 73 75 76 26 76 112 110 112 100 112 91 99 99 58 99 36...
result:
ok 290080 lines
Test #9:
score: 0
Accepted
time: 220ms
memory: 24948kb
input:
10000 9 9 1 2 3 1 3 6 3 6 2 1 9 1 7 9 7 7 6 6 2 7 6 8 3 6 4 6 10 10 1 1 3 3 5 2 7 3 6 8 7 4 9 3 10 10 8 9 4 5 1 9 9 4 6 8 5 4 2 9 9 1 1 2 4 4 5 4 4 5 2 9 8 2 2 8 1 3 5 6 1 9 3 2 8 4 6 8 8 1 2 3 1 2 5 2 1 6 8 4 7 1 8 4 8 3 7 3 8 1 1 5 9 9 1 2 1 3 5 3 7 1 7 2 6 3 4 3 7 7 9 7 4 4 4 4 8 6 4 4 10 10 1 1 ...
output:
65 90 70 35 68 88 85 84 85 39 82 86 96 82 87 41 86 93 88 101 98 75 102 104 102 103 100 97 52 52 42 52 51 56 52 41 61 57 64 38 66 23 23 60 23 87 116 86 115 118 136 87 135 129 115 123 130 82 120 82 119 120 133 132 129 85 89 87 90 41 85 86 45 63 53 48 23 46 35 45 47 41 36 58 64 62 62 61 67 20 69 56 56 ...
result:
ok 289972 lines
Test #10:
score: 0
Accepted
time: 303ms
memory: 43488kb
input:
10000 9 9 1 2 2 1 2 3 1 1 3 3 3 3 2 7 8 2 3 5 1 1 9 2 3 1 7 5 8 8 1 1 2 4 5 1 7 6 6 6 2 4 8 4 7 2 4 8 7 2 1 6 5 9 9 1 2 2 2 1 4 2 1 5 2 3 1 8 5 8 2 1 5 7 2 2 5 4 3 8 1 9 9 1 2 1 4 4 4 2 8 5 7 1 2 7 7 7 4 9 2 7 7 8 2 3 6 8 5 9 9 1 1 2 4 3 6 7 5 2 2 7 8 3 5 7 2 6 4 7 3 5 9 6 6 2 7 10 10 1 2 1 2 4 6 6 ...
output:
74 74 111 117 119 104 117 118 120 10 34 40 39 31 23 34 19 121 125 122 121 125 123 121 123 125 66 69 33 65 63 33 62 79 80 24 17 38 38 39 29 17 21 38 66 74 70 50 68 69 45 70 45 81 95 103 96 100 75 75 75 61 100 91 87 92 92 86 43 55 86 82 80 95 100 102 49 25 108 71 94 104 89 92 98 91 94 93 96 63 63 98 6...
result:
ok 289954 lines
Test #11:
score: 0
Accepted
time: 308ms
memory: 62520kb
input:
10000 9 9 1 1 3 1 4 3 5 7 7 7 7 6 2 3 2 6 2 7 4 1 6 5 6 7 6 7 8 8 1 1 2 1 5 6 2 8 2 8 3 1 1 6 8 1 4 2 8 3 5 8 4 8 8 1 2 1 4 3 1 5 3 2 5 5 7 8 4 4 6 7 2 8 2 1 1 3 9 9 1 2 3 2 3 3 3 7 9 9 4 4 4 3 9 9 8 6 3 8 6 1 1 1 7 6 8 8 1 1 3 3 2 2 1 4 1 7 1 4 7 2 8 2 2 8 5 4 8 1 5 10 10 1 2 2 3 4 2 3 6 7 3 5 10 3...
output:
44 68 70 73 72 71 74 68 68 37 46 40 50 45 37 44 38 29 20 39 27 39 41 35 37 42 61 121 42 122 121 126 51 123 55 55 60 55 44 56 56 55 101 127 51 83 127 125 127 131 123 127 44 132 135 118 79 136 128 137 137 128 112 92 99 92 111 108 106 106 114 112 55 56 51 60 55 54 55 56 52 22 42 53 31 44 45 45 50 45 40...
result:
ok 289847 lines
Test #12:
score: 0
Accepted
time: 276ms
memory: 24844kb
input:
10000 8 8 1 1 3 3 1 4 2 2 5 1 3 7 1 2 7 7 8 1 6 5 6 4 4 8 8 1 2 1 3 4 6 5 4 3 5 3 6 4 6 4 5 5 2 8 4 8 7 2 9 9 1 2 3 3 1 2 3 4 5 6 1 3 2 8 5 2 7 5 6 1 8 3 8 5 2 8 9 9 1 1 1 2 4 6 3 3 3 9 6 2 6 5 6 3 6 6 4 5 4 5 9 4 3 4 8 8 1 1 3 4 2 5 1 1 2 7 2 4 2 8 3 1 7 5 1 2 4 3 6 9 9 1 2 1 4 5 1 3 5 9 6 1 9 7 4 ...
output:
51 48 51 53 54 43 50 30 30 20 20 20 14 26 33 30 94 92 91 91 92 55 85 86 91 53 67 68 69 34 66 66 68 67 32 42 39 35 40 39 39 37 42 58 54 50 49 42 61 51 53 18 88 68 78 85 36 81 63 24 84 28 40 31 39 38 24 38 30 84 73 75 57 82 78 57 65 84 68 70 53 70 53 67 68 50 71 74 72 23 31 45 66 73 65 22 108 101 102 ...
result:
ok 290127 lines
Test #13:
score: 0
Accepted
time: 287ms
memory: 43492kb
input:
10000 9 9 1 1 3 2 3 1 1 3 9 8 3 9 5 8 1 9 6 4 7 3 2 2 8 8 2 5 9 9 1 2 1 3 5 4 7 6 9 5 2 3 6 1 4 1 2 9 1 1 8 5 5 8 5 1 9 9 1 1 2 1 4 1 1 2 8 3 9 1 4 6 6 1 9 4 1 9 7 6 3 3 9 2 8 8 1 2 3 2 1 3 1 5 6 8 5 6 7 3 6 2 8 2 7 4 2 5 3 9 9 1 1 3 1 2 6 1 2 2 1 1 4 5 9 1 4 3 6 6 9 7 4 7 7 5 4 8 8 1 2 1 3 5 2 4 3 ...
output:
118 105 112 117 106 117 74 55 75 24 29 38 27 35 24 42 42 36 114 119 71 121 105 119 122 57 103 56 56 60 59 55 55 55 55 90 87 92 87 94 81 96 28 88 38 38 21 37 21 44 35 21 37 42 48 33 46 42 48 14 39 32 95 97 39 78 94 63 96 106 86 34 100 104 97 85 99 113 106 71 47 65 70 67 39 60 63 64 60 74 53 60 52 60 ...
result:
ok 289926 lines
Test #14:
score: 0
Accepted
time: 242ms
memory: 62296kb
input:
10000 8 8 1 2 1 2 4 2 7 4 5 2 6 5 8 1 1 7 7 6 5 2 1 4 4 10 10 1 1 2 2 5 6 5 3 6 3 8 10 8 8 3 9 3 5 5 1 1 7 2 2 9 7 2 2 10 8 8 1 1 1 1 3 3 6 5 7 8 8 4 5 4 4 5 2 4 2 4 2 3 3 9 9 1 1 1 4 5 6 6 5 1 3 1 3 6 3 9 3 3 6 1 2 5 9 8 5 8 1 8 8 1 2 1 3 5 3 6 1 5 7 3 5 2 5 7 1 5 1 3 5 5 5 7 9 9 1 2 3 1 2 1 7 2 7 ...
output:
54 54 52 39 34 55 51 28 104 96 104 49 90 69 103 94 103 103 64 20 58 29 58 58 58 54 49 49 74 71 74 49 61 65 74 40 33 38 36 40 37 27 36 93 87 94 79 90 28 93 88 93 52 43 49 45 45 43 31 54 48 52 31 22 53 52 50 46 104 107 100 94 102 96 108 105 104 96 112 92 115 94 93 62 111 92 107 62 32 44 44 33 42 23 44...
result:
ok 289769 lines
Test #15:
score: 0
Accepted
time: 260ms
memory: 62328kb
input:
10000 8 8 1 2 1 3 4 6 4 1 8 8 5 7 7 5 4 1 6 3 1 8 7 1 8 9 9 1 2 3 2 5 1 7 4 4 8 9 6 3 9 4 8 4 7 3 9 5 2 6 1 2 6 8 8 1 2 2 4 2 4 6 6 5 1 1 8 4 2 6 7 4 7 8 1 2 1 6 9 9 1 1 1 4 4 2 1 5 2 7 1 4 4 4 8 3 5 2 6 7 2 6 7 6 6 9 10 10 1 1 2 1 1 4 3 2 6 3 7 2 5 10 9 3 5 5 7 1 7 1 10 1 9 8 3 3 6 9 9 1 1 3 2 5 3 ...
output:
35 41 12 40 36 33 34 35 59 57 42 59 58 42 50 54 51 67 31 67 62 53 68 61 63 59 90 78 86 94 94 93 94 82 137 133 136 129 136 135 129 133 87 130 78 78 71 64 80 65 64 71 65 164 168 165 164 164 167 167 167 166 163 36 40 36 37 37 37 39 38 95 92 92 86 94 57 92 87 90 80 29 57 55 60 59 57 51 57 54 64 39 59 64...
result:
ok 290030 lines
Test #16:
score: 0
Accepted
time: 228ms
memory: 43528kb
input:
10000 8 8 1 2 1 4 5 6 7 8 8 7 5 3 5 5 5 8 4 4 6 1 7 1 2 8 8 1 1 3 3 2 5 4 4 3 7 1 8 5 6 3 2 8 5 7 4 4 2 8 8 8 1 1 1 3 1 4 2 2 5 7 1 7 8 5 6 5 8 4 8 7 8 7 1 9 9 1 1 2 3 2 2 1 7 6 6 7 6 4 7 3 5 7 9 8 6 2 5 6 4 4 2 9 9 1 2 3 3 2 5 2 5 8 5 8 5 6 6 9 6 3 1 4 2 4 7 7 5 9 7 8 8 1 2 3 4 4 2 1 3 8 3 5 5 2 3 ...
output:
8 25 30 20 30 27 32 20 38 42 41 42 44 27 26 44 59 57 60 58 60 59 60 57 43 87 87 55 59 92 93 86 85 103 103 45 104 99 99 96 77 78 44 40 46 42 43 48 33 49 62 66 45 45 31 70 62 64 67 34 80 86 78 75 48 86 80 84 82 71 64 70 69 68 63 58 68 62 138 145 154 156 151 114 157 151 113 158 51 31 51 22 49 51 50 44 ...
result:
ok 289869 lines
Test #17:
score: 0
Accepted
time: 332ms
memory: 25392kb
input:
10000 8 8 1 1 2 3 3 4 6 7 8 1 6 2 3 5 8 2 1 2 5 8 4 2 5 8 8 1 2 3 2 4 2 4 4 2 7 8 5 8 7 4 6 4 6 4 7 4 1 7 8 8 1 1 2 2 2 4 3 6 3 3 2 5 1 7 5 6 1 2 5 3 2 7 8 8 8 1 1 2 3 3 5 7 6 8 8 8 4 1 1 6 7 3 8 2 8 1 7 2 8 8 1 2 3 3 2 1 7 8 3 1 4 6 5 8 2 3 3 3 6 1 3 5 7 9 9 1 2 1 3 2 5 5 8 3 7 9 6 5 9 1 1 4 2 3 1 ...
output:
43 36 37 34 31 38 42 38 57 59 59 58 41 41 58 50 54 53 52 52 52 49 53 57 39 11 30 36 37 43 41 42 50 48 46 46 36 45 47 50 56 65 51 34 51 57 56 55 48 23 65 66 74 74 69 74 23 63 116 113 119 66 112 116 99 105 116 113 59 53 25 59 41 41 49 59 116 110 125 110 83 110 123 109 111 122 79 74 79 79 75 51 51 51 5...
result:
ok 289830 lines
Test #18:
score: 0
Accepted
time: 300ms
memory: 62476kb
input:
10000 8 8 1 2 2 4 3 3 4 4 7 7 7 5 1 4 7 6 4 3 6 3 1 2 6 10 10 1 1 1 4 1 5 3 1 9 10 10 4 9 9 2 3 3 8 1 7 1 4 8 1 10 8 7 3 9 8 8 1 2 2 2 5 6 5 6 5 1 8 8 6 3 5 4 8 8 7 2 1 3 7 8 8 1 2 2 4 4 3 3 8 6 1 7 2 6 1 6 8 3 3 2 3 2 8 4 8 8 1 2 2 1 2 3 2 8 1 7 6 5 7 8 5 1 5 1 2 2 2 3 3 8 8 1 1 1 2 3 6 4 6 6 1 4 1...
output:
59 23 56 59 59 45 55 55 50 149 147 98 147 150 150 147 153 148 56 64 57 63 64 58 57 66 60 56 55 56 45 54 54 59 75 76 78 76 51 74 72 50 22 38 39 44 43 39 22 27 41 21 41 40 41 49 51 47 126 109 135 122 135 129 126 133 51 135 135 135 101 140 135 135 140 134 137 134 45 59 45 56 60 60 56 45 220 219 74 218 ...
result:
ok 290002 lines
Test #19:
score: 0
Accepted
time: 240ms
memory: 24708kb
input:
10000 10 10 1 2 1 1 3 5 6 6 1 5 9 1 3 6 6 1 5 8 10 9 5 9 9 5 10 3 4 9 8 10 10 1 1 3 4 1 1 1 2 9 5 2 1 1 4 1 7 1 7 2 9 4 9 2 3 4 7 10 7 3 10 10 1 2 3 3 4 3 7 3 7 2 2 2 3 2 10 8 6 9 1 10 4 1 6 7 5 4 2 9 6 8 8 1 2 3 1 5 4 5 2 7 1 8 8 7 1 3 2 3 7 5 1 4 5 6 8 8 1 1 3 2 1 4 4 2 2 8 5 8 1 2 6 3 7 5 2 2 3 5...
output:
102 95 60 86 101 102 31 87 96 62 137 128 133 129 132 138 101 101 135 132 122 182 187 188 184 187 186 185 184 184 30 30 40 32 27 39 34 25 26 49 46 39 40 27 43 14 57 66 64 54 62 38 59 67 59 110 113 75 75 111 112 75 111 113 83 97 23 93 95 94 83 86 86 84 156 144 159 69 156 159 143 156 145 73 168 165 168...
result:
ok 289994 lines
Test #20:
score: 0
Accepted
time: 317ms
memory: 43408kb
input:
10000 9 9 1 2 3 4 5 2 2 1 2 4 1 9 9 2 2 4 7 4 8 5 9 5 7 3 1 5 8 8 1 2 1 1 5 2 2 8 1 5 3 5 3 5 2 1 1 3 1 3 4 7 3 9 9 1 1 3 1 1 2 2 7 6 5 2 9 2 8 3 5 1 4 5 7 8 2 1 1 7 6 9 9 1 2 1 2 5 1 1 5 3 1 9 6 1 7 1 5 4 9 4 9 8 1 1 3 3 4 8 8 1 1 2 3 3 6 5 5 5 6 3 7 2 1 4 3 4 2 4 3 1 8 4 10 10 1 1 3 3 2 5 4 8 4 3 ...
output:
67 43 63 67 68 70 72 65 71 63 65 65 64 54 63 64 58 86 81 79 87 87 93 79 84 93 99 78 89 102 104 104 89 99 100 26 38 44 33 42 23 39 45 90 94 97 97 87 47 96 96 69 90 114 118 110 110 119 121 120 114 119 82 43 51 31 44 46 16 52 52 68 33 66 70 71 70 37 71 57 51 51 52 34 18 18 49 73 64 74 66 61 70 49 65 75...
result:
ok 289988 lines
Test #21:
score: 0
Accepted
time: 268ms
memory: 62820kb
input:
10000 8 8 1 2 2 2 2 4 4 6 6 3 7 8 7 5 3 1 6 8 4 6 2 4 4 10 10 1 2 3 4 3 5 5 6 7 4 4 1 10 4 9 9 4 7 5 6 9 6 1 3 2 6 2 9 10 10 10 1 1 1 3 4 5 3 5 3 1 8 9 3 6 6 6 2 6 5 7 1 10 5 4 2 7 3 3 9 8 8 1 2 3 1 3 3 3 6 8 5 8 4 8 1 6 3 8 5 5 7 3 2 4 8 8 1 1 2 1 5 4 2 2 6 2 1 1 5 7 4 5 8 1 2 8 4 4 1 8 8 1 2 3 4 4...
output:
41 86 70 82 82 69 81 68 70 91 82 82 68 51 77 74 76 91 147 145 44 130 153 151 145 129 145 145 66 71 66 70 65 19 65 68 51 48 44 31 51 48 45 50 60 59 59 51 54 59 55 45 74 73 77 77 75 75 75 75 160 171 160 160 157 170 168 158 159 171 90 90 117 114 118 117 107 114 37 113 47 37 45 37 19 45 50 48 121 116 11...
result:
ok 290036 lines
Test #22:
score: 0
Accepted
time: 267ms
memory: 25108kb
input:
10000 9 9 1 2 2 1 2 2 7 3 8 1 6 1 2 4 4 4 2 7 6 5 2 9 9 9 1 9 9 9 1 1 3 1 5 6 5 7 9 5 3 5 7 5 1 3 4 6 7 4 6 6 8 1 8 7 8 8 1 1 3 2 1 5 1 2 1 5 5 4 7 5 2 1 1 7 5 2 5 1 6 10 10 1 1 2 1 5 3 2 7 4 10 3 5 6 4 10 9 3 3 3 4 6 7 7 4 7 9 3 7 7 9 9 1 2 2 4 3 2 1 7 7 8 4 6 9 7 4 3 8 3 2 1 8 6 8 3 2 5 9 9 1 1 2 ...
output:
113 111 109 55 110 112 111 38 113 62 64 61 56 68 70 45 63 62 51 28 57 41 48 29 41 49 96 59 55 69 66 95 46 97 69 46 86 86 57 85 86 83 87 86 84 48 68 63 54 20 68 17 61 65 69 49 49 25 70 69 66 60 66 105 112 68 117 117 116 69 113 113 115 49 45 47 48 45 48 39 40 160 169 172 159 169 170 171 171 169 160 79...
result:
ok 289982 lines
Test #23:
score: 0
Accepted
time: 292ms
memory: 43456kb
input:
10000 8 8 1 1 2 3 2 4 6 7 8 3 4 5 2 2 4 5 3 5 3 2 2 1 7 9 9 1 2 3 1 4 1 3 2 9 6 5 8 9 7 7 4 5 8 3 1 3 1 2 7 1 8 9 9 1 1 3 3 5 1 1 5 8 2 6 4 1 7 8 5 7 3 3 2 5 7 2 4 6 8 9 9 1 2 3 1 3 2 5 1 6 4 4 6 2 1 8 1 8 5 9 2 7 2 3 1 1 2 8 8 1 2 2 2 4 1 1 7 7 7 4 5 8 4 5 8 2 3 4 8 6 4 4 10 10 1 1 1 4 1 5 4 8 4 6 ...
output:
42 43 42 38 23 23 36 42 80 82 76 83 82 80 80 75 81 90 96 89 103 99 99 103 100 104 62 62 76 69 47 77 71 80 76 27 67 66 63 65 63 68 42 154 154 172 171 111 171 154 153 154 173 112 113 112 112 114 113 114 108 109 105 122 123 125 131 132 55 122 123 123 65 62 53 63 61 53 64 67 166 81 165 166 166 133 161 1...
result:
ok 289985 lines
Test #24:
score: 0
Accepted
time: 1ms
memory: 3904kb
input:
2 2 1 1 2 1 2 4 1 1 1 1 2 2 1 2 2
output:
3 2 3 3 2
result:
ok 5 lines
Test #25:
score: 0
Accepted
time: 271ms
memory: 62268kb
input:
10000 9 9 1 1 3 1 4 2 6 4 6 1 9 1 2 2 7 3 8 5 8 3 3 8 7 4 8 3 9 9 1 2 1 1 3 1 1 5 9 5 1 5 1 5 4 7 1 4 6 7 7 9 2 8 6 5 10 10 1 2 3 2 5 6 5 1 6 10 2 4 2 1 1 10 7 3 4 5 5 4 8 3 2 6 1 4 6 8 8 1 2 3 3 2 4 2 2 8 1 4 7 8 5 7 1 4 4 6 5 5 7 5 8 8 1 2 1 4 5 4 6 8 7 3 7 6 8 6 2 2 8 1 7 2 8 5 3 8 8 1 1 1 1 3 6 ...
output:
63 62 34 58 65 58 58 64 58 67 98 98 98 97 103 100 100 104 114 102 68 86 69 100 113 101 115 116 57 65 66 58 65 65 28 58 39 39 21 42 43 36 43 41 50 59 59 59 50 49 58 49 45 49 54 52 52 54 45 16 14 15 25 23 27 26 26 23 85 94 94 92 93 88 94 91 54 154 177 176 85 177 177 177 103 171 175 92 94 94 92 92 59 9...
result:
ok 290047 lines
Test #26:
score: 0
Accepted
time: 247ms
memory: 62276kb
input:
10000 10 10 1 1 2 4 3 4 3 1 1 8 9 5 8 2 8 2 10 1 1 1 8 5 7 9 8 6 5 7 7 10 10 1 2 3 2 5 1 3 4 2 3 1 2 10 2 6 2 6 10 2 9 5 6 3 4 3 8 8 6 1 9 9 1 1 3 3 5 2 3 1 8 1 2 3 6 4 5 8 4 3 1 5 1 4 2 5 8 6 10 10 1 1 1 4 4 3 5 6 6 7 2 5 2 8 10 4 4 8 1 10 2 4 7 9 3 3 7 1 9 10 10 1 1 3 3 3 2 5 7 9 8 8 1 2 10 8 7 7 ...
output:
126 135 130 126 120 125 90 126 135 45 134 127 129 129 127 137 135 116 58 131 91 92 88 87 85 92 91 94 88 100 114 113 105 114 117 114 118 67 116 26 69 90 45 75 87 65 78 62 78 83 29 73 84 29 37 73 83 70 74 75 77 74 73 26 76 74 33 38 35 40 40 26 49 48 86 78 102 101 96 30 87 75 84 100 62 64 23 57 46 73 6...
result:
ok 290027 lines
Test #27:
score: 0
Accepted
time: 265ms
memory: 43468kb
input:
10000 10 10 1 2 2 2 3 2 7 4 5 8 7 4 9 10 4 10 5 5 10 6 10 4 2 7 8 6 10 8 9 8 8 1 2 2 2 3 3 1 5 8 5 4 4 4 8 8 6 4 8 1 8 1 4 8 8 8 1 2 3 4 3 5 6 3 5 2 7 8 1 5 7 1 6 3 3 6 4 4 8 10 10 1 1 3 1 1 1 3 2 8 1 6 5 2 3 3 3 8 2 3 7 7 4 8 4 9 5 10 2 6 9 9 1 1 3 4 3 6 3 4 7 3 2 2 2 5 2 6 1 8 3 9 5 3 1 7 9 9 9 9 ...
output:
111 111 167 111 111 168 164 111 168 168 64 62 31 22 66 43 43 64 41 44 42 23 41 36 41 42 169 171 150 152 176 85 153 178 178 171 93 32 98 95 93 95 95 95 39 146 145 148 147 148 146 147 146 147 49 51 50 53 42 51 51 43 35 99 100 100 102 97 100 99 101 99 33 71 65 51 70 71 67 66 136 131 129 135 118 115 129...
result:
ok 290108 lines
Extra Test:
score: 0
Extra Test Passed