#line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/library/cpp-dump.hpp" #ifndef ONLINE_JUDGE #else #define dump(...) #define CPP_DUMP_SET_OPTION(...) #define CPP_DUMP_SET_OPTION_GLOBAL(...) #define CPP_DUMP_DEFINE_EXPORT_OBJECT(...) #define CPP_DUMP_DEFINE_EXPORT_ENUM(...) #define CPP_DUMP_DEFINE_EXPORT_OBJECT_GENERIC(...) #endif void init_cpp_dump() { // ログのラベルを行番号にする CPP_DUMP_SET_OPTION(log_label_func, cp::log_label::filename()); // 記号に色を付ける CPP_DUMP_SET_OPTION(es_value, (cp::types::es_value_t{ "\x1b[02m", // log: 灰色 "\x1b[34m", // expression: 青 "\x1b[38;5;39m", // reserved: 明るい青 "\x1b[38;5;150m", // number: 明るい緑 "\x1b[38;5;172m", // character: オレンジ "\x1b[38;5;220m", // escaped_char: 明るいオレンジ "\x1b[02m", // op: 灰色 "\x1b[32m", // identifier: 緑 "\x1b[96m", // member: 明るいシアン "\x1b[31m", // unsupported: 赤 { "\x1b[33m", // bracket_by_depth[0]: 黄色 "\x1b[35m", // bracket_by_depth[1]: マゼンタ "\x1b[36m", // bracket_by_depth[2]: シアン }, "\x1b[02m", // class_op: 灰色 "\x1b[02m", // member_op: 灰色 "", // number_op: デフォルト })); CPP_DUMP_SET_OPTION(detailed_class_es, true); CPP_DUMP_SET_OPTION(detailed_member_es, true); CPP_DUMP_SET_OPTION(detailed_number_es, true); CPP_DUMP_SET_OPTION(es_style, cp::types::es_style_t::by_syntax); } #line 7 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/alias.hpp" #include // #include #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/bits/stdc++.h" // C++ includes used for precompiling -*- C++ -*- // Copyright (C) 2003-2022 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file stdc++.h * This is an implementation file for a precompiled header. */ // 17.4.1.2 Headers // C #ifndef _GLIBCXX_NO_ASSERT #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include #include #include #endif // C++ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif #if __cplusplus >= 201402L #include #endif #if __cplusplus >= 201703L #include #include // #include #include #include #include #include #include #endif #if __cplusplus >= 202002L #include #include #include #include #if __cpp_impl_coroutine # include #endif #include #include #include #include #include #include #include #include #include #endif #if __cplusplus > 202002L #include #include #if __has_include() # include #endif #include #endif #line 7 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/alias.hpp" using namespace std; // using namespace std::views; // using namespace boost::multiprecision; // --- 型エイリアス --- using ll = long long; using ull = unsigned long long; template using vec = vector; template using vvec = vector>; template using vvvec = vector>>; template using p_queue = priority_queue; template using rp_queue = priority_queue, greater>; using bint = boost::multiprecision::cpp_int; // --- 黒魔術 --- #define int ll // --- 制御マクロ --- #define rep(i, n) for (ll i = 0; i < n; ++i) #define all(v) begin(v), end(v) // #define BIT(n) (1LL << (n)) #define MAX(type) numeric_limits::max() #define MIN(type) numeric_limits::min() #define yes cout << "Yes" << endl #define no cout << "No" << endl #define pb push_back #define mp make_pair #define fir first #define sec second // --- 定数 --- constexpr ll INF = 1LL << 60; // constexpr ll INF = numeric_limits::max(); inline signed bit_width(ll x) { return bit_width((ull)x); } inline ull bit_ceil(ll x) { return bit_ceil((ull)x); } #line 9 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/concepts.hpp" template concept addable = requires(T a, T b) { { a + b } -> convertible_to; }; #line 10 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/debug.hpp" // --- デバッグ --- #ifndef ONLINE_JUDGE #else #define line_debug() ; #define coutd(x) ; #define printd(x) ; #endif #line 11 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/int128_t.hpp" using int128_t = __int128_t; using uint128_t = __uint128_t; using lll = int128_t; using ulll = uint128_t; // https://kenkoooo.hatenablog.com/entry/2016/11/30/163533 ostream &operator<<(ostream &dest, lll value) { ostream::sentry s(dest); if (s) { lll tmp = value < 0 ? -value : value; char buffer[128]; char *d = end(buffer); do { --d; *d = "0123456789"[tmp % 10]; tmp /= 10; } while (tmp != 0); if (value < 0) { --d; *d = '-'; } int len = end(buffer) - d; if (dest.rdbuf()->sputn(d, len) != len) { dest.setstate(ios_base::badbit); } } return dest; } lll string_to_lll(string &s) { lll ret = 0; for (int i = 0; i < s.length(); i++) if ('0' <= s[i] && s[i] <= '9') ret = 10 * ret + s[i] - '0'; return ret; } istream &operator>>(istream &src, lll &value) { string s; src >> s; value = string_to_lll(s); return src; } #line 12 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/print.hpp" // --------------- // ----- TOC ----- template ostream &operator<<(ostream &os, const pair &p); template istream &operator>>(istream &is, pair &p); template ostream &operator<<(ostream &os, const vector &v); template ostream &operator<<(ostream &os, const vector> &v); template ostream &operator<<(ostream &os, const vector>> &v); template istream &operator>>(istream &is, vector &v); template ostream &operator<<(ostream &os, const map &mp); template ostream &operator<<(ostream &os, const set &st); template ostream &operator<<(ostream &os, const multiset &st); template ostream &operator<<(ostream &os, queue q); template ostream &operator<<(ostream &os, deque q); template ostream &operator<<(ostream &os, stack st); template ostream &operator<<(ostream &os, priority_queue pq); // --- END TOC --- // --------------- template ostream &operator<<(ostream &os, const pair &p) { os << "(" << p.first << "," << p.second << ")"; return os; } template istream &operator>>(istream &is, pair &p) { is >> p.first >> p.second; return is; } template ostream &operator<<(ostream &os, const vector &v) { os << "["; for (int i = 0; i < (int)v.size(); i++) { os << v[i] << (i + 1 != (int)v.size() ? ", " : "]"); } return os; } template ostream &operator<<(ostream &os, const vector> &v) { for (int i = 0; i < (int)v.size(); i++) { os << v[i] << endl; } return os; } template ostream &operator<<(ostream &os, const vector>> &v) { for (int i = 0; i < (int)v.size(); i++) { os << "i = " << i << endl; os << v[i]; } return os; } template istream &operator>>(istream &is, vector &v) { for (T &in : v) is >> in; return is; } template ostream &operator<<(ostream &os, const map &mp) { for (auto &[key, val] : mp) { os << key << ":" << val << " "; } return os; } template ostream &operator<<(ostream &os, const set &st) { os << "{"; auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? ", " : "}"); itr++; } return os; } template ostream &operator<<(ostream &os, const multiset &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; } template ostream &operator<<(ostream &os, queue q) { while (q.size()) { os << q.front() << " "; q.pop(); } return os; } template ostream &operator<<(ostream &os, deque q) { while (q.size()) { os << q.front() << " "; q.pop_front(); } return os; } template ostream &operator<<(ostream &os, stack st) { while (st.size()) { os << st.top() << " "; st.pop(); } return os; } template ostream &operator<<(ostream &os, priority_queue pq) { while (pq.size()) { os << pq.top() << " "; pq.pop(); } return os; } #line 13 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/util.hpp" // --- Utils --- // 二分探索 template inline T bin_search(T ok, T ng, const function is_ok) { assert(is_ok(ok)); assert(!is_ok(ng)); assert(ok < ng); while (abs(ok - ng) > 1) { T mid = (ok + ng) / 2; if (is_ok(mid)) ok = mid; else ng = mid; } return ok; } // 順列全探索 inline void rep_perm(int n, function &)> f) { vec v(n); iota(v.begin(), v.end(), 0); do { f(v); } while (next_permutation(v.begin(), v.end())); } inline void rep_bit(int n, function f) { rep(i, 1LL << n) f(i); } // 配列 to string template inline string join(const vec &v, string sep = " ") { string res = ""; rep(i, v.size()) res += to_string(v[i]) + (i == v.size() - 1 ? "" : sep); return res; } template inline void join_out(ostream &os, const vec &v, string sep = " ", string end = "\n") { int n = v.size(); rep(i, n) os << v[i] << (i == n - 1 ? end : sep); } template inline void transform(vec &src, function f) { for (auto &val : src) f(val); } // ベース指定ceil inline ll ceil(ll x, ll base) { return (x + base - 1) / base * base; } // ベース指定floor inline ll floor(ll x, ll base) { return x / base * base; } // 合計値を求める // ll sum(const vec &v) { return accumulate(all(v), 0LL); } template T sum(const vec &v) { return accumulate(all(v), T()); } // 可変引数min template auto min(T... a) { return min(initializer_list>{a...}); } // 可変引数max template auto max(T... a) { return max(initializer_list>{a...}); } template bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; } template bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; } // 3項間不等式 // 広義単調増加 inline bool is_increasing(int x, int y, int z) { return x <= y && y <= z; } // 半開区間[x, z)にyが含まれるか? inline bool is_contained(int x, int y, int z) { return x <= y && y < z; } // 頂点(x, y)が範囲に含まれるか inline bool is_contained(int H, int W, int x, int y) { return is_contained(0, x, H) && is_contained(0, y, W); } // rootに対し、aとbが同じ側にあるか (=は含まない) inline bool is_same_side(int root, int a, int b) { return (root < a) == (root < b); } // vector継承にする? template struct vec_accumulate : public vec { explicit vec_accumulate(vec &v) : vec(v.size()) { assert(v.size() > 0); this->at(0) = v[0]; for (int i = 1; i < v.size(); ++i) this->at(i) = this->at(i - 1) + v[i]; } // [0, i]の和 // なので、-1 <= i < size() T operator[](int i) { assert(is_contained(-1, i, this->size())); if (i == -1) return T(); return this->at(i); } }; // vector func template inline void unique_erase(vec &v) { sort(all(v)); v.erase(unique(all(v)), v.end()); } // view struct to_vec_adoptor { friend constexpr auto operator|(std::ranges::viewable_range auto &&r, to_vec_adoptor self) { auto r_common = r | std::views::common; return std::vector(r_common.begin(), r_common.end()); } }; inline constexpr to_vec_adoptor to_vec; void io_setup() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << std::fixed << std::setprecision(15); } #line 14 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/pow.hpp" // 繰り返し2乗法 template constexpr T powi(T a, F n) { T ans = 1; while (n > 0) { if (n & 1) ans *= a; a *= a; n >>= 1; } return ans; } template constexpr T pow(T a, F n) { return powi(a, n); } constexpr ll powm(ll a, ll n, const ll mod) { lll ans = 1; while (n > 0) { if (n & 1) ans = ans * a % mod; a = ((lll)a) * a % mod; n >>= 1; } return ans; } #line 16 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/common/template.hpp" #line 2 "/home/zoi/document/kyopro/under_greeen_3/main.cpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/2d/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/2d/area.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/2d/point.hpp" class Point { public: int x, y; Point() : x(0), y(0) {} Point(int x, int y) : x(x), y(y) {} Point up() const { return Point(x - 1, y); } Point down() const { return Point(x + 1, y); } Point left() const { return Point(x, y - 1); } Point right() const { return Point(x, y + 1); } Point upper_left() const { return Point(x - 1, y - 1); } Point upper_right() const { return Point(x - 1, y + 1); } Point lower_left() const { return Point(x + 1, y - 1); } Point lower_right() const { return Point(x + 1, y + 1); } vec around4() const { return {up(), down(), left(), right()}; } vec around8() const { return {up(), up().right(), right(), right().down(), down(), down().left(), left(), left().up()}; } int manhattan() const { return std::abs(x) + std::abs(y); } int eucurid2() const { return x * x + y * y; } bool operator==(const Point &p) const { return x == p.x && y == p.y; } bool operator!=(const Point &p) const { return !(*this == p); } void operator+=(const Point &p) { x += p.x; y += p.y; } void operator-=(const Point &p) { x -= p.x; y -= p.y; } Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); } Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); } bool operator<(const Point &p) const { return x == p.x ? y < p.y : x < p.x; } bool operator>(const Point &p) const { return x == p.x ? y > p.y : x > p.x; } }; ostream &operator<<(ostream &os, const Point &p) { os << p.x << p.y; return os; } istream &operator>>(istream &is, Point &p) { is >> p.x >> p.y; return is; } inline bool is_contained(int H, int W, Point p) { return is_contained(H, W, p.x, p.y); } #line 4 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/2d/area.hpp" class Area { public: int H, W; bool allow_outside = false; char out_val; Area(int H, int W) : H(H), W(W), data(vector(H, string(W, '.'))) {} Area(int H, int W, char out_val) : H(H), W(W), data(vector(H, string(W, '.'))), allow_outside(true), out_val(out_val) {} string &operator[](int i) { return data[i]; } // 時計回りで90度回転 Area rotated90() const { Area ret(W, H); rep(i, H) rep(j, W) ret[j][H - i - 1] = data[i][j]; return ret; } void rotate90() { assert(H == W); data = rotated90().data; } char at(int x, int y) { if (is_contained(H, W, x, y)) return data[x][y]; else if (allow_outside) return out_val; else { cerr << "[Area::at] out of range" << endl; assert(false); } } void set(int x, int y, char val) { if (is_contained(H, W, x, y)) data[x][y] = val; else if (allow_outside) return; else { cerr << "[Area::set] out of range" << endl; assert(false); } } bool contains(int x, int y) const { return is_contained(H, W, x, y); } bool contains(Point p) const { return is_contained(H, W, p.x, p.y); } private: vec data; }; ostream &operator<<(ostream &os, Area &a) { rep(i, a.H) os << a[i] << endl; return os; } istream &operator>>(istream &is, Area &a) { rep(i, a.H) is >> a[i]; return is; } #line 4 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/2d/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/2d/rect.hpp" class Rect { public: int x, y, w, h; Rect(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {} int area() const { return w * h; } }; #line 6 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/2d/all.hpp" #line 4 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/all.hpp" // #include "3d/all.hpp" // #include "convolution/all.hpp" // #include "datastructure/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/cycle.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/template.hpp" // Node template struct WeightedNode { int id; T cost = numeric_limits::max(); WeightedNode(int id, T cost) : id(id), cost(cost) {} }; template struct WeightState { public: int location; T used_cost; WeightState(int location, T used_cost) : location(location), used_cost(used_cost) {} bool operator<(const WeightState &n) const { return used_cost < n.used_cost; } bool operator>(const WeightState &n) const { return used_cost > n.used_cost; } }; // Graph struct Graph { private: const int n; const bool directed; vec> edges; public: explicit Graph(int n, bool directed = false) : n(n), directed(directed), edges(n) {} inline void add_edge(int u, int v) { edges[u].emplace_back(v); if (!directed) edges[v].emplace_back(u); } inline vec &operator[](int i) { return edges[i]; } inline int size() const { return n; } }; template struct WeightedGraph { private: const int n; const bool directed; public: vec>> edges; explicit WeightedGraph(int n, bool directed = false) : n(n), directed(directed), edges(n) {} inline void add_edge(int u, int v, T w) { edges[u].emplace_back(WeightedNode(v, w)); if (!directed) edges[v].emplace_back(WeightedNode(u, w)); } inline vec> &operator[](int i) { return edges[i]; } inline int size() const { return n; } }; // template using WeightedGraph = vec>>; template using WGraph = WeightedGraph; #line 4 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/cycle.hpp" bool has_cycle(Graph &g, int start = 0) { vec seen(g.size(), 0); vec finished(g.size(), 0); auto dfs = [&](auto fn, int index) { seen[index] = 1; for (auto next : g[index]) { if (finished[next]) continue; if (seen[next] && !finished[next]) return true; if (fn(fn, next)) return true; } finished[index] = 1; return false; }; return dfs(dfs, start); } #line 2 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/depth.hpp" struct TreeNodeInfo { public: TreeNodeInfo(int parent, int depth) : parent(parent), depth(depth) {} int parent; int depth; }; vec depth(Graph &graph, int root = 0) { vec result(graph.size(), TreeNodeInfo(-1, -1)); stack st; st.push(root); result[root] = TreeNodeInfo(root, 0); while (!st.empty()) { int index = st.top(); st.pop(); for (auto next : graph[index]) { if (result[next].depth != -1) continue; result[next] = TreeNodeInfo(index, result[index].depth + 1); st.push(next); } } return result; } #line 3 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/diameter.hpp" int diameter(Graph &graph, int start = 0) { vec seen(graph.size(), 0); auto dfs = [&](auto fn, int index) -> pair { // max-cost, index pair result = {0, index}; seen[index] = 1; for (auto next : graph[index]) { if (seen[next]) continue; auto next_result = fn(fn, next); next_result.first += 1; result = max(result, next_result); } seen[index] = 0; return result; }; auto result = dfs(dfs, start); result = dfs(dfs, result.second); return result.first; } template int diameter(WGraph &graph, int start = 0) { auto dfs = [&](int index) -> pair { vec result(graph.size(), -1); T mx = 0; int mx_index = index; stack st; st.push(index); result[index] = 0; while (!st.empty()) { int current = st.top(); st.pop(); for (auto next : graph[current]) { if (result[next.id] >= 0) continue; st.push(next.id); result[next.id] = result[current] + next.cost; if (chmax(mx, result[next.id])) { mx_index = next.id; } } } return {mx, mx_index}; }; auto result = dfs(start); result = dfs(result.second); return result.first; } #line 4 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/dijkstra.hpp" template vec dijkstra(WGraph &graph, int start) { vec way(graph.size(), INF); rp_queue> q; q.push(WeightState(start, 0)); way[start] = 0; while (!q.empty()) { WeightState current = q.top(); q.pop(); for (auto &next : graph[current.location]) { T next_cost = current.used_cost + next.cost; if (way[next.id] <= next_cost) continue; way[next.id] = next_cost; q.push(WeightState(next.id, way[next.id])); } } return way; } #line 5 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/lca.hpp" struct LCA { private: Graph graph; int root; // parent[k][v] := vの2^k先の親 vec> parent; vec depth_data; public: explicit LCA(Graph &graph, int root = 0) : graph(graph), root(root), depth_data(depth(graph, root)) { int n = graph.size(); int logn = 1; while ((1 << logn) < n) logn++; parent = vector(logn, vector(n, -1LL)); for (int i = 0; i < n; i++) parent[0][i] = depth_data[i].parent; // ダブリング for (int k = 0; k + 1 < logn; k++) { for (int i = 0; i < n; i++) { if (parent[k][i] < 0) parent[k + 1][i] = -1; else parent[k + 1][i] = parent[k][parent[k][i]]; } } } int query(int u, int v) const { if (depth_data[u].depth > depth_data[v].depth) swap(u, v); int logn = parent.size(); // uとvの深さが同じになるまで親を辿る rep(k, logn) { if ((depth_data[v].depth - depth_data[u].depth) >> k & 1) { v = parent[k][v]; } } // にぶたん if (u == v) return u; for (int k = logn - 1; k >= 0; k--) { if (parent[k][u] != parent[k][v]) { u = parent[k][u]; v = parent[k][v]; } } return parent[0][u]; } }; #line 6 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/topological-sort.hpp" vec topological_sort(Graph &graph) { vec result; vec deleted(graph.size(), false); vec in_count(graph.size()); rep(i, graph.size()) { for (auto next : graph[i]) { in_count[next]++; } } queue q; rep(i, graph.size()) { if (in_count[i] == 0) { q.push(i); } } while (!q.empty()) { int now = q.front(); q.pop(); result.emplace_back(now); deleted[now] = true; for (auto next : graph[now]) { if (deleted[next]) continue; in_count[next]--; if (in_count[next] == 0) { q.push(next); } } } return result; } #line 8 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/graph/all.hpp" #line 8 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/all.hpp" // #include "combination.hpp" // #include "factorial.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/modint.hpp" namespace modint_utils { constexpr inline int32_t normalize(int val, int32_t mod) { return (val % mod + mod) % mod; } constexpr inline int32_t inv(int32_t a, int32_t mod) { int32_t b = mod, u = 1, v = 0; while (b) { int32_t t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); } u %= mod; if (u < 0) u += mod; return u; // return mod_pow(val, mod - 2, mod); } } // namespace modint_utils template struct dynamic_modint { private: int _val; public: dynamic_modint() : dynamic_modint(0) {} dynamic_modint(int val) : _val(modint_utils::normalize(val, MOD)) {} // logic int val() const { return _val; } inline dynamic_modint inv() const { return dynamic_modint(modint_utils::inv(_val, MOD)); } inline dynamic_modint pow(const int n) const { return dynamic_modint(powm(_val, n, MOD)); } inline static constexpr dynamic_modint pow(const dynamic_modint &a, const int n) { return dynamic_modint(mod_pow(a._val, n, a.MOD)); } // op inline dynamic_modint &operator++() { return *this += 1; } inline dynamic_modint &operator--() { return *this -= 1; } inline dynamic_modint operator++(int32_t) const { dynamic_modint tmp = *this; ++*this; return tmp; } inline dynamic_modint operator--(int32_t) { dynamic_modint tmp = *this; --*this; return tmp; } inline dynamic_modint operator+(const dynamic_modint &a) const { return dynamic_modint(_val) += a; } inline dynamic_modint operator-(const dynamic_modint &a) const { return dynamic_modint(_val) -= a; } inline dynamic_modint operator*(const dynamic_modint &a) const { return dynamic_modint(_val) *= a; } inline dynamic_modint operator/(const dynamic_modint &a) const { return dynamic_modint(_val) /= a; } inline bool operator==(const dynamic_modint &a) { return _val == a._val; } inline bool operator!=(const dynamic_modint &a) { return _val != a._val; } inline dynamic_modint &operator+=(const dynamic_modint &a) { _val += a.val(); if (_val >= MOD) _val -= MOD; return *this; } inline dynamic_modint &operator-=(const dynamic_modint &a) { _val -= a.val(); if (_val < 0) _val += MOD; return *this; } inline dynamic_modint &operator*=(const dynamic_modint &a) { _val = _val * a.val() % MOD; return *this; } inline dynamic_modint &operator/=(const dynamic_modint &a) { *this *= modint_utils::inv(a.val(), MOD); return *this; } explicit operator int() const { return _val; } // io friend ostream &operator<<(ostream &os, const dynamic_modint &a) { return os << a._val; } friend istream &operator>>(istream &os, dynamic_modint &a) { os >> a._val; a._val = modint_utils::normalize(a._val, MOD); return os; } }; // using modint998 = modint<998244353>; template ostream &operator<<(ostream &os, const dynamic_modint &i) { os << i.val(); return os; } template ostream &operator<<(ostream &os, const vector> &v) { for (int i = 0; i < (int)v.size(); i++) { os << v[i].val() << (i + 1 != (int)v.size() ? " " : ""); } return os; } template struct modint { private: using i32 = int32_t; i32 _val; public: consteval inline modint() noexcept : _val(0) {} constexpr inline modint(int val) noexcept : _val(modint_utils::normalize(val, MOD)) {} constexpr inline modint(modint const &val) noexcept : _val(val._val) {} // logic constexpr i32 val() const noexcept { return _val; } constexpr modint pow(const int n) const { return modint(powm(_val, n, MOD)); } constexpr inline static modint pow(const modint &a, const int n) noexcept { return modint(mod_pow(a._val, n, a.MOD)); } constexpr inline modint inv() const noexcept { return modint(modint_utils::inv(_val, MOD)); } // op constexpr inline modint &operator++() noexcept { return *this += 1; } constexpr inline modint &operator--() noexcept { return *this -= 1; } constexpr inline modint operator++(int32_t) noexcept { modint tmp = *this; ++*this; return tmp; } constexpr inline modint operator--(int32_t) noexcept { modint tmp = *this; --*this; return tmp; } constexpr inline modint operator+(const modint &a) const noexcept { return modint(*this) += a; } constexpr inline modint operator-(const modint &a) const noexcept { return modint(*this) -= a; } constexpr inline modint operator*(const modint &a) const noexcept { return modint(*this) *= a; } constexpr inline modint operator/(const modint &a) const noexcept { return modint(*this) /= a; } constexpr inline bool operator==(const modint &a) const noexcept { return _val == a.val(); } constexpr inline bool operator!=(const modint &a) const noexcept { return _val != a.val(); } constexpr inline modint &operator+=(const modint &a) noexcept { _val += a._val; if (_val >= MOD) _val -= MOD; return *this; } constexpr inline modint &operator-=(const modint &a) noexcept { _val -= a._val; if (_val < 0) _val += MOD; return *this; } constexpr inline modint &operator*=(const modint &a) noexcept { _val = (ll)_val * a._val % MOD; return *this; } constexpr inline modint &operator/=(const modint &a) noexcept { *this *= modint_utils::inv(a.val(), MOD); return *this; } explicit operator int() const noexcept { return _val; } // io friend ostream &operator<<(ostream &os, const modint &a) noexcept { return os << a._val; } friend istream &operator>>(istream &os, modint &a) noexcept { os >> a._val; a._val = modint_utils::normalize(a._val, MOD); return os; } }; using mint998 = modint<998244353>; #line 6 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/prime.hpp" // ミラーラビン素数判定法 // O(k log^3 n) // https://drken1215.hatenablog.com/entry/2023/05/23/233000 bool MillerRabin(long long N, vector A) { long long s = 0, d = N - 1; while (d % 2 == 0) { ++s; d >>= 1; } for (auto a : A) { if (N <= a) return true; long long t, x = powm(a, d, N); if (x != 1) { for (t = 0; t < s; ++t) { if (x == N - 1) break; x = __int128_t(x) * x % N; } if (t == s) return false; } } return true; } bool is_prime(long long N) { if (N <= 1) return false; if (N == 2) return true; if (N % 2 == 0) return false; if (N < 4759123141LL) return MillerRabin(N, {2, 7, 61}); else return MillerRabin(N, {2, 325, 9375, 28178, 450775, 9780504, 1795265022}); } // ポラード・ロー素因数分解法 // 値が大きい場合に有効、ちゃんと調べる! // O(n^(1/4)) // https://lpha-z.hatenablog.com/entry/2023/01/15/231500 // https://algo-method.com/tasks/553/editorial uint64_t pollard_rho(uint64_t N) { if (N % 2 == 0) return 2; if (is_prime(N)) return N; uint64_t step = 0; auto f = [&](uint64_t x) -> uint64_t { return (__int128_t(x) * x + step) % N; }; while (true) { ++step; uint64_t x = step, y = f(x); while (true) { uint64_t p = gcd(y - x + N, N); if (p == 0 || p == N) break; if (p != 1) return p; x = f(x); y = f(f(y)); } } } // 素因数分解 // https://algo-method.com/tasks/553/editorial struct PrimeFactor { uint64_t prime; uint64_t exp; }; vec prime_factorize(uint64_t N) { if (N == 1) return {}; uint64_t p = pollard_rho(N); if (p == N) return {{p, 1}}; auto left = prime_factorize(p); auto right = prime_factorize(N / p); left.insert(left.end(), all(right)); sort(all(left), [](const PrimeFactor &a, const PrimeFactor &b) { return a.prime < b.prime; }); vec ans; rep(i, left.size()) { if (i == 0 || left[i].prime != left[i - 1].prime) ans.emplace_back(left[i]); else ans.back().exp += left[i].exp; } return ans; } #line 8 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/rational.hpp" template struct Rational { T num, den; Rational(T num) : num(num), den(1) {} Rational(T num, T den) : num(num), den(den) { T g = gcd(num, den); this->num /= g; this->den /= g; } Rational operator+(const Rational &rhs) const { return Rational(num * rhs.den + rhs.num * den, den * rhs.den); } Rational operator-(const Rational &rhs) const { return Rational(num * rhs.den - rhs.num * den, den * rhs.den); } Rational operator*(const Rational &rhs) const { return Rational(num * rhs.num, den * rhs.den); } Rational operator/(const Rational &rhs) const { return Rational(num * rhs.den, den * rhs.num); } bool operator<(const Rational &rhs) const { return num * rhs.den < rhs.num * den; } bool operator>(const Rational &rhs) const { return num * rhs.den > rhs.num * den; } bool operator==(const Rational &rhs) const { return num * rhs.den == rhs.num * den; } bool operator!=(const Rational &rhs) const { return !(*this == rhs); } bool operator<=(const Rational &rhs) const { return (*this < rhs) || (*this == rhs); } bool operator>=(const Rational &rhs) const { return (*this > rhs) || (*this == rhs); } friend ostream &operator<<(ostream &os, const Rational &r) { return os << r.num << "/" << r.den; } void operator+=(const Rational &rhs) { *this = *this + rhs; } void operator-=(const Rational &rhs) { *this = *this - rhs; } void operator*=(const Rational &rhs) { *this = *this * rhs; } void operator/=(const Rational &rhs) { *this = *this / rhs; } double val() const { return (double)num / den; } // operator double() const { return val(); } // operator string() const { return to_string(num) + "/" + to_string(den); } Rational pow(ll n) const { if (n == 0) { return Rational(1); } else if (n < 0) { return Rational(den, num).pow(-n); } else { Rational res = pow(n / 2); res *= res; if (n % 2 == 1) { res *= *this; } return res; } } }; #line 9 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/math/all.hpp" #line 9 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/all.hpp" // #include "string/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/util/all.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/util/inversion-num.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/datastructure/comp.hpp" // https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/4/DSL_4_A template struct comp { private: const int _n; int _cmp_n; vec _raw, _comp; public: explicit comp(const vec &src) : _n(src.size()), _cmp_n(0), _raw(src), _comp(_n, 0) { sort(_raw.begin(), _raw.end()); _raw.erase(unique(_raw.begin(), _raw.end()), _raw.end()); _cmp_n = _raw.size(); rep(i, _n) _comp[i] = lower_bound(_raw.begin(), _raw.end(), src[i]) - _raw.begin(); } inline int size() const { return _n; } inline int cmp_size() const { return _cmp_n; } inline T get_raw(int complessed) { assert(0 <= complessed && complessed < _cmp_n); return _raw[complessed]; } inline T operator[](int i) { assert(0 <= i && i < _n); return _comp[i]; } inline T get_comp(int raw) { return lower_bound(_raw.begin(), _raw.end(), raw) - _raw.begin(); } }; #line 4 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/util/inversion-num.hpp" #line 1 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/datastructure/fenwick-tree.hpp" template struct FenwickTree { private: T _n; vec _data; public: explicit FenwickTree(T n) : _n(n), _data(n + 1, 0) {} explicit FenwickTree(const vec &src) : _n(src.size()), _data(_n + 1, 0) { rep(i, _n) add(i, src[i]); } void add(int i, T val) { i++; while (i <= _n) { _data[i] += val; i += i & -i; } } // [0, i] int sum(int i) const { i++; T ans = 0; while (i > 0) { ans += _data[i]; i -= i & -i; } return ans; } // [l, r) int sum(int l, int r) const { return sum(r - 1) - sum(l - 1); } }; #line 5 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/util/inversion-num.hpp" int inversion_num(const vec &a) { comp c(a); int n = a.size(); FenwickTree bit(n); int ans = 0; rep(i, n) { ans += i - bit.sum(c[i]); bit.add(c[i], 1); } return ans; } #line 4 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/util/all.hpp" #line 11 "/home/zoi/ghq/github.com/ZOI-dayo/atcoder-library/all.hpp" #line 3 "/home/zoi/document/kyopro/under_greeen_3/main.cpp" using mint = modint<998'244'353>; struct Data { int a, b; auto operator()(int x) const { return a * x + b; } auto operator+(const Data &d) const { return Data{a + d.a, b + d.b}; } }; void solve() { int n, s, b; cin >> n >> s >> b; vec h(n); cin >> h; int height = h[0] + s * b; for (int i = 1; i < n; ++i) { if(height < h[i]){ no; return; } int new_available_height = h[i] + s * b; chmax(height, new_available_height); } yes; } void test() { } signed main() { io_setup(); init_cpp_dump(); // input solve(); // test(); }