QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#620815 | #415. 最小生成树 | maspy | 100 ✓ | 102ms | 51804kb | C++20 | 39.2kb | 2024-10-07 21:30:46 | 2024-10-07 21:30:47 |
Judging History
answer
#line 1 "/home/maspy/compro/library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
// https://codeforces.com/blog/entry/96344
#pragma GCC optimize("Ofast,unroll-loops")
// いまの CF だとこれ入れると動かない?
// #pragma GCC target("avx2,popcnt")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;
template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'010'000'000;
template <>
constexpr ll infty<ll> = 2'020'000'000'000'000'000;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * 2'000'000'000'000'000'000;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;
using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...) \
vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)
#define FOR_subset(t, s) for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define stoi stoll
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
template <typename T>
T floor(T a, T b) {
return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
T q = floor(x, y);
return {q, x - q * y};
}
template <typename T, typename U>
T SUM(const vector<U> &A) {
T sm = 0;
for (auto &&a: A) sm += a;
return sm;
}
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()
template <typename T>
T POP(deque<T> &que) {
T a = que.front();
que.pop_front();
return a;
}
template <typename T>
T POP(pq<T> &que) {
T a = que.top();
que.pop();
return a;
}
template <typename T>
T POP(pqg<T> &que) {
T a = que.top();
que.pop();
return a;
}
template <typename T>
T POP(vc<T> &que) {
T a = que.back();
que.pop_back();
return a;
}
template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
if (check_ok) assert(check(ok));
while (abs(ok - ng) > 1) {
auto x = (ng + ok) / 2;
(check(x) ? ok : ng) = x;
}
return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
FOR(iter) {
double x = (ok + ng) / 2;
(check(x) ? ok : ng) = x;
}
return (ok + ng) / 2;
}
template <class T, class S>
inline bool chmax(T &a, const S &b) {
return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
return (a > b ? a = b, 1 : 0);
}
// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
vc<int> A(S.size());
FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
return A;
}
template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
int N = A.size();
vector<T> B(N + 1);
FOR(i, N) { B[i + 1] = B[i] + A[i]; }
if (off == 0) B.erase(B.begin());
return B;
}
// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
vector<int> ids(len(A));
iota(all(ids), 0);
sort(all(ids), [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
return ids;
}
// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
vc<T> B(len(I));
FOR(i, len(I)) B[i] = A[I[i]];
return B;
}
template <typename T, typename... Vectors>
void concat(vc<T> &first, const Vectors &... others) {
vc<T> &res = first;
(res.insert(res.end(), others.begin(), others.end()), ...);
}
#endif
#line 1 "/home/maspy/compro/library/other/io.hpp"
#define FASTIO
#include <unistd.h>
// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;
struct Pre {
char num[10000][4];
constexpr Pre() : num() {
for (int i = 0; i < 10000; i++) {
int n = i;
for (int j = 3; j >= 0; j--) {
num[i][j] = n % 10 | '0';
n /= 10;
}
}
}
} constexpr pre;
inline void load() {
memcpy(ibuf, ibuf + pil, pir - pil);
pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
pil = 0;
if (pir < SZ) ibuf[pir++] = '\n';
}
inline void flush() {
fwrite(obuf, 1, por, stdout);
por = 0;
}
void rd(char &c) {
do {
if (pil + 1 > pir) load();
c = ibuf[pil++];
} while (isspace(c));
}
void rd(string &x) {
x.clear();
char c;
do {
if (pil + 1 > pir) load();
c = ibuf[pil++];
} while (isspace(c));
do {
x += c;
if (pil == pir) load();
c = ibuf[pil++];
} while (!isspace(c));
}
template <typename T>
void rd_real(T &x) {
string s;
rd(s);
x = stod(s);
}
template <typename T>
void rd_integer(T &x) {
if (pil + 100 > pir) load();
char c;
do
c = ibuf[pil++];
while (c < '-');
bool minus = 0;
if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
if (c == '-') { minus = 1, c = ibuf[pil++]; }
}
x = 0;
while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
if (minus) x = -x;
}
}
void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }
template <class T, class U>
void rd(pair<T, U> &p) {
return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
if constexpr (N < std::tuple_size<T>::value) {
auto &x = std::get<N>(t);
rd(x);
rd_tuple<N + 1>(t);
}
}
template <class... T>
void rd(tuple<T...> &tpl) {
rd_tuple(tpl);
}
template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
for (auto &d: x) rd(d);
}
void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
rd(h), read(t...);
}
void wt(const char c) {
if (por == SZ) flush();
obuf[por++] = c;
}
void wt(const string s) {
for (char c: s) wt(c);
}
void wt(const char *s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; i++) wt(s[i]);
}
template <typename T>
void wt_integer(T x) {
if (por > SZ - 100) flush();
if (x < 0) { obuf[por++] = '-', x = -x; }
int outi;
for (outi = 96; x >= 10000; outi -= 4) {
memcpy(out + outi, pre.num[x % 10000], 4);
x /= 10000;
}
if (x >= 1000) {
memcpy(obuf + por, pre.num[x], 4);
por += 4;
} else if (x >= 100) {
memcpy(obuf + por, pre.num[x] + 1, 3);
por += 3;
} else if (x >= 10) {
int q = (x * 103) >> 10;
obuf[por] = q | '0';
obuf[por + 1] = (x - q * 10) | '0';
por += 2;
} else
obuf[por++] = x | '0';
memcpy(obuf + por, out + outi + 4, 96 - outi);
por += 96 - outi;
}
template <typename T>
void wt_real(T x) {
ostringstream oss;
oss << fixed << setprecision(15) << double(x);
string s = oss.str();
wt(s);
}
void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }
template <class T, class U>
void wt(const pair<T, U> val) {
wt(val.first);
wt(' ');
wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
if constexpr (N < std::tuple_size<T>::value) {
if constexpr (N > 0) { wt(' '); }
const auto x = std::get<N>(t);
wt(x);
wt_tuple<N + 1>(t);
}
}
template <class... T>
void wt(tuple<T...> tpl) {
wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) wt(' ');
wt(val[i]);
}
}
template <class T>
void wt(const vector<T> val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) wt(' ');
wt(val[i]);
}
}
void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
wt(head);
if (sizeof...(Tail)) wt(' ');
print(forward<Tail>(tail)...);
}
// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;
#if defined(LOCAL)
#define SHOW(...) SHOW_IMPL(__VA_ARGS__, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, SHOW1)(__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
#define SHOW1(x) print(#x, "=", (x)), flush()
#define SHOW2(x, y) print(#x, "=", (x), #y, "=", (y)), flush()
#define SHOW3(x, y, z) print(#x, "=", (x), #y, "=", (y), #z, "=", (z)), flush()
#define SHOW4(x, y, z, w) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush()
#define SHOW5(x, y, z, w, v) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v)), flush()
#define SHOW6(x, y, z, w, v, u) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v), #u, "=", (u)), flush()
#else
#define SHOW(...)
#endif
#define INT(...) \
int __VA_ARGS__; \
read(__VA_ARGS__)
#define LL(...) \
ll __VA_ARGS__; \
read(__VA_ARGS__)
#define U32(...) \
u32 __VA_ARGS__; \
read(__VA_ARGS__)
#define U64(...) \
u64 __VA_ARGS__; \
read(__VA_ARGS__)
#define STR(...) \
string __VA_ARGS__; \
read(__VA_ARGS__)
#define CHAR(...) \
char __VA_ARGS__; \
read(__VA_ARGS__)
#define DBL(...) \
double __VA_ARGS__; \
read(__VA_ARGS__)
#define VEC(type, name, size) \
vector<type> name(size); \
read(name)
#define VV(type, name, h, w) \
vector<vector<type>> name(h, vector<type>(w)); \
read(name)
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 3 "main.cpp"
#line 2 "/home/maspy/compro/library/ds/unionfind/unionfind.hpp"
struct UnionFind {
int n, n_comp;
vc<int> dat; // par or (-size)
UnionFind(int n = 0) { build(n); }
void build(int m) {
n = m, n_comp = m;
dat.assign(n, -1);
}
void reset() { build(n); }
int operator[](int x) {
while (dat[x] >= 0) {
int pp = dat[dat[x]];
if (pp < 0) { return dat[x]; }
x = dat[x] = pp;
}
return x;
}
ll size(int x) {
x = (*this)[x];
return -dat[x];
}
bool merge(int x, int y) {
x = (*this)[x], y = (*this)[y];
if (x == y) return false;
if (-dat[x] < -dat[y]) swap(x, y);
dat[x] += dat[y], dat[y] = x, n_comp--;
return true;
}
vc<int> get_all() {
vc<int> A(n);
FOR(i, n) A[i] = (*this)[i];
return A;
}
};
#line 2 "/home/maspy/compro/library/graph/base.hpp"
template <typename T>
struct Edge {
int frm, to;
T cost;
int id;
};
template <typename T = int, bool directed = false>
struct Graph {
static constexpr bool is_directed = directed;
int N, M;
using cost_type = T;
using edge_type = Edge<T>;
vector<edge_type> edges;
vector<int> indptr;
vector<edge_type> csr_edges;
vc<int> vc_deg, vc_indeg, vc_outdeg;
bool prepared;
class OutgoingEdges {
public:
OutgoingEdges(const Graph* G, int l, int r) : G(G), l(l), r(r) {}
const edge_type* begin() const {
if (l == r) { return 0; }
return &G->csr_edges[l];
}
const edge_type* end() const {
if (l == r) { return 0; }
return &G->csr_edges[r];
}
private:
const Graph* G;
int l, r;
};
bool is_prepared() { return prepared; }
Graph() : N(0), M(0), prepared(0) {}
Graph(int N) : N(N), M(0), prepared(0) {}
void build(int n) {
N = n, M = 0;
prepared = 0;
edges.clear();
indptr.clear();
csr_edges.clear();
vc_deg.clear();
vc_indeg.clear();
vc_outdeg.clear();
}
void add(int frm, int to, T cost = 1, int i = -1) {
assert(!prepared);
assert(0 <= frm && 0 <= to && to < N);
if (i == -1) i = M;
auto e = edge_type({frm, to, cost, i});
edges.eb(e);
++M;
}
#ifdef FASTIO
// wt, off
void read_tree(bool wt = false, int off = 1) { read_graph(N - 1, wt, off); }
void read_graph(int M, bool wt = false, int off = 1) {
for (int m = 0; m < M; ++m) {
INT(a, b);
a -= off, b -= off;
if (!wt) {
add(a, b);
} else {
T c;
read(c);
add(a, b, c);
}
}
build();
}
#endif
void build() {
assert(!prepared);
prepared = true;
indptr.assign(N + 1, 0);
for (auto&& e: edges) {
indptr[e.frm + 1]++;
if (!directed) indptr[e.to + 1]++;
}
for (int v = 0; v < N; ++v) { indptr[v + 1] += indptr[v]; }
auto counter = indptr;
csr_edges.resize(indptr.back() + 1);
for (auto&& e: edges) {
csr_edges[counter[e.frm]++] = e;
if (!directed)
csr_edges[counter[e.to]++] = edge_type({e.to, e.frm, e.cost, e.id});
}
}
OutgoingEdges operator[](int v) const {
assert(prepared);
return {this, indptr[v], indptr[v + 1]};
}
vc<int> deg_array() {
if (vc_deg.empty()) calc_deg();
return vc_deg;
}
pair<vc<int>, vc<int>> deg_array_inout() {
if (vc_indeg.empty()) calc_deg_inout();
return {vc_indeg, vc_outdeg};
}
int deg(int v) {
if (vc_deg.empty()) calc_deg();
return vc_deg[v];
}
int in_deg(int v) {
if (vc_indeg.empty()) calc_deg_inout();
return vc_indeg[v];
}
int out_deg(int v) {
if (vc_outdeg.empty()) calc_deg_inout();
return vc_outdeg[v];
}
#ifdef FASTIO
void debug() {
print("Graph");
if (!prepared) {
print("frm to cost id");
for (auto&& e: edges) print(e.frm, e.to, e.cost, e.id);
} else {
print("indptr", indptr);
print("frm to cost id");
FOR(v, N) for (auto&& e: (*this)[v]) print(e.frm, e.to, e.cost, e.id);
}
}
#endif
vc<int> new_idx;
vc<bool> used_e;
// G における頂点 V[i] が、新しいグラフで i になるようにする
// {G, es}
// sum(deg(v)) の計算量になっていて、
// 新しいグラフの n+m より大きい可能性があるので注意
Graph<T, directed> rearrange(vc<int> V, bool keep_eid = 0) {
if (len(new_idx) != N) new_idx.assign(N, -1);
int n = len(V);
FOR(i, n) new_idx[V[i]] = i;
Graph<T, directed> G(n);
vc<int> history;
FOR(i, n) {
for (auto&& e: (*this)[V[i]]) {
if (len(used_e) <= e.id) used_e.resize(e.id + 1);
if (used_e[e.id]) continue;
int a = e.frm, b = e.to;
if (new_idx[a] != -1 && new_idx[b] != -1) {
history.eb(e.id);
used_e[e.id] = 1;
int eid = (keep_eid ? e.id : -1);
G.add(new_idx[a], new_idx[b], e.cost, eid);
}
}
}
FOR(i, n) new_idx[V[i]] = -1;
for (auto&& eid: history) used_e[eid] = 0;
G.build();
return G;
}
Graph<T, true> to_directed_tree(int root = -1) {
if (root == -1) root = 0;
assert(!is_directed && prepared && M == N - 1);
Graph<T, true> G1(N);
vc<int> par(N, -1);
auto dfs = [&](auto& dfs, int v) -> void {
for (auto& e: (*this)[v]) {
if (e.to == par[v]) continue;
par[e.to] = v, dfs(dfs, e.to);
}
};
dfs(dfs, root);
for (auto& e: edges) {
int a = e.frm, b = e.to;
if (par[a] == b) swap(a, b);
assert(par[b] == a);
G1.add(a, b, e.cost);
}
G1.build();
return G1;
}
private:
void calc_deg() {
assert(vc_deg.empty());
vc_deg.resize(N);
for (auto&& e: edges) vc_deg[e.frm]++, vc_deg[e.to]++;
}
void calc_deg_inout() {
assert(vc_indeg.empty());
vc_indeg.resize(N);
vc_outdeg.resize(N);
for (auto&& e: edges) { vc_indeg[e.to]++, vc_outdeg[e.frm]++; }
}
};
#line 2 "/home/maspy/compro/library/graph/tree.hpp"
#line 4 "/home/maspy/compro/library/graph/tree.hpp"
// HLD euler tour をとっていろいろ。
template <typename GT>
struct Tree {
using Graph_type = GT;
GT &G;
using WT = typename GT::cost_type;
int N;
vector<int> LID, RID, head, V, parent, VtoE;
vc<int> depth;
vc<WT> depth_weighted;
Tree(GT &G, int r = 0, bool hld = 1) : G(G) { build(r, hld); }
void build(int r = 0, bool hld = 1) {
if (r == -1) return; // build を遅延したいとき
N = G.N;
LID.assign(N, -1), RID.assign(N, -1), head.assign(N, r);
V.assign(N, -1), parent.assign(N, -1), VtoE.assign(N, -1);
depth.assign(N, -1), depth_weighted.assign(N, 0);
assert(G.is_prepared());
int t1 = 0;
dfs_sz(r, -1, hld);
dfs_hld(r, t1);
}
void dfs_sz(int v, int p, bool hld) {
auto &sz = RID;
parent[v] = p;
depth[v] = (p == -1 ? 0 : depth[p] + 1);
sz[v] = 1;
int l = G.indptr[v], r = G.indptr[v + 1];
auto &csr = G.csr_edges;
// 使う辺があれば先頭にする
for (int i = r - 2; i >= l; --i) {
if (hld && depth[csr[i + 1].to] == -1) swap(csr[i], csr[i + 1]);
}
int hld_sz = 0;
for (int i = l; i < r; ++i) {
auto e = csr[i];
if (depth[e.to] != -1) continue;
depth_weighted[e.to] = depth_weighted[v] + e.cost;
VtoE[e.to] = e.id;
dfs_sz(e.to, v, hld);
sz[v] += sz[e.to];
if (hld && chmax(hld_sz, sz[e.to]) && l < i) { swap(csr[l], csr[i]); }
}
}
void dfs_hld(int v, int ×) {
LID[v] = times++;
RID[v] += LID[v];
V[LID[v]] = v;
bool heavy = true;
for (auto &&e: G[v]) {
if (depth[e.to] <= depth[v]) continue;
head[e.to] = (heavy ? head[v] : e.to);
heavy = false;
dfs_hld(e.to, times);
}
}
vc<int> heavy_path_at(int v) {
vc<int> P = {v};
while (1) {
int a = P.back();
for (auto &&e: G[a]) {
if (e.to != parent[a] && head[e.to] == v) {
P.eb(e.to);
break;
}
}
if (P.back() == a) break;
}
return P;
}
int heavy_child(int v) {
int k = LID[v] + 1;
if (k == N) return -1;
int w = V[k];
return (parent[w] == v ? w : -1);
}
int e_to_v(int eid) {
auto e = G.edges[eid];
return (parent[e.frm] == e.to ? e.frm : e.to);
}
int v_to_e(int v) { return VtoE[v]; }
int get_eid(int u, int v) {
if (parent[u] != v) swap(u, v);
assert(parent[u] == v);
return VtoE[u];
}
int ELID(int v) { return 2 * LID[v] - depth[v]; }
int ERID(int v) { return 2 * RID[v] - depth[v] - 1; }
// 目標地点へ進む個数が k
int LA(int v, int k) {
assert(k <= depth[v]);
while (1) {
int u = head[v];
if (LID[v] - k >= LID[u]) return V[LID[v] - k];
k -= LID[v] - LID[u] + 1;
v = parent[u];
}
}
int la(int u, int v) { return LA(u, v); }
int LCA(int u, int v) {
for (;; v = parent[head[v]]) {
if (LID[u] > LID[v]) swap(u, v);
if (head[u] == head[v]) return u;
}
}
int meet(int a, int b, int c) { return LCA(a, b) ^ LCA(a, c) ^ LCA(b, c); }
int lca(int u, int v) { return LCA(u, v); }
int subtree_size(int v, int root = -1) {
if (root == -1) return RID[v] - LID[v];
if (v == root) return N;
int x = jump(v, root, 1);
if (in_subtree(v, x)) return RID[v] - LID[v];
return N - RID[x] + LID[x];
}
int dist(int a, int b) {
int c = LCA(a, b);
return depth[a] + depth[b] - 2 * depth[c];
}
WT dist_weighted(int a, int b) {
int c = LCA(a, b);
return depth_weighted[a] + depth_weighted[b] - WT(2) * depth_weighted[c];
}
// a is in b
bool in_subtree(int a, int b) { return LID[b] <= LID[a] && LID[a] < RID[b]; }
int jump(int a, int b, ll k) {
if (k == 1) {
if (a == b) return -1;
return (in_subtree(b, a) ? LA(b, depth[b] - depth[a] - 1) : parent[a]);
}
int c = LCA(a, b);
int d_ac = depth[a] - depth[c];
int d_bc = depth[b] - depth[c];
if (k > d_ac + d_bc) return -1;
if (k <= d_ac) return LA(a, k);
return LA(b, d_ac + d_bc - k);
}
vc<int> collect_child(int v) {
vc<int> res;
for (auto &&e: G[v])
if (e.to != parent[v]) res.eb(e.to);
return res;
}
vc<int> collect_light(int v) {
vc<int> res;
bool skip = true;
for (auto &&e: G[v])
if (e.to != parent[v]) {
if (!skip) res.eb(e.to);
skip = false;
}
return res;
}
vc<pair<int, int>> get_path_decomposition(int u, int v, bool edge) {
// [始点, 終点] の"閉"区間列。
vc<pair<int, int>> up, down;
while (1) {
if (head[u] == head[v]) break;
if (LID[u] < LID[v]) {
down.eb(LID[head[v]], LID[v]);
v = parent[head[v]];
} else {
up.eb(LID[u], LID[head[u]]);
u = parent[head[u]];
}
}
if (LID[u] < LID[v]) down.eb(LID[u] + edge, LID[v]);
elif (LID[v] + edge <= LID[u]) up.eb(LID[u], LID[v] + edge);
reverse(all(down));
up.insert(up.end(), all(down));
return up;
}
// 辺の列の情報 (frm,to,str)
// str = "heavy_up", "heavy_down", "light_up", "light_down"
vc<tuple<int, int, string>> get_path_decomposition_detail(int u, int v) {
vc<tuple<int, int, string>> up, down;
while (1) {
if (head[u] == head[v]) break;
if (LID[u] < LID[v]) {
if (v != head[v]) down.eb(head[v], v, "heavy_down"), v = head[v];
down.eb(parent[v], v, "light_down"), v = parent[v];
} else {
if (u != head[u]) up.eb(u, head[u], "heavy_up"), u = head[u];
up.eb(u, parent[u], "light_up"), u = parent[u];
}
}
if (LID[u] < LID[v]) down.eb(u, v, "heavy_down");
elif (LID[v] < LID[u]) up.eb(u, v, "heavy_up");
reverse(all(down));
concat(up, down);
return up;
}
vc<int> restore_path(int u, int v) {
vc<int> P;
for (auto &&[a, b]: get_path_decomposition(u, v, 0)) {
if (a <= b) {
FOR(i, a, b + 1) P.eb(V[i]);
} else {
FOR_R(i, b, a + 1) P.eb(V[i]);
}
}
return P;
}
// path [a,b] と [c,d] の交わり. 空ならば {-1,-1}.
// https://codeforces.com/problemset/problem/500/G
pair<int, int> path_intersection(int a, int b, int c, int d) {
int ab = lca(a, b), ac = lca(a, c), ad = lca(a, d);
int bc = lca(b, c), bd = lca(b, d), cd = lca(c, d);
int x = ab ^ ac ^ bc, y = ab ^ ad ^ bd; // meet(a,b,c), meet(a,b,d)
if (x != y) return {x, y};
int z = ac ^ ad ^ cd;
if (x != z) x = -1;
return {x, x};
}
};
#line 2 "/home/maspy/compro/library/graph/ds/tree_monoid.hpp"
#line 2 "/home/maspy/compro/library/ds/segtree/segtree.hpp"
template <class Monoid>
struct SegTree {
using MX = Monoid;
using X = typename MX::value_type;
using value_type = X;
vc<X> dat;
int n, log, size;
SegTree() {}
SegTree(int n) { build(n); }
template <typename F>
SegTree(int n, F f) {
build(n, f);
}
SegTree(const vc<X>& v) { build(v); }
void build(int m) {
build(m, [](int i) -> X { return MX::unit(); });
}
void build(const vc<X>& v) {
build(len(v), [&](int i) -> X { return v[i]; });
}
template <typename F>
void build(int m, F f) {
n = m, log = 1;
while ((1 << log) < n) ++log;
size = 1 << log;
dat.assign(size << 1, MX::unit());
FOR(i, n) dat[size + i] = f(i);
FOR_R(i, 1, size) update(i);
}
X get(int i) { return dat[size + i]; }
vc<X> get_all() { return {dat.begin() + size, dat.begin() + size + n}; }
void update(int i) { dat[i] = Monoid::op(dat[2 * i], dat[2 * i + 1]); }
void set(int i, const X& x) {
assert(i < n);
dat[i += size] = x;
while (i >>= 1) update(i);
}
void multiply(int i, const X& x) {
assert(i < n);
i += size;
dat[i] = Monoid::op(dat[i], x);
while (i >>= 1) update(i);
}
X prod(int L, int R) {
assert(0 <= L && L <= R && R <= n);
X vl = Monoid::unit(), vr = Monoid::unit();
L += size, R += size;
while (L < R) {
if (L & 1) vl = Monoid::op(vl, dat[L++]);
if (R & 1) vr = Monoid::op(dat[--R], vr);
L >>= 1, R >>= 1;
}
return Monoid::op(vl, vr);
}
X prod_all() { return dat[1]; }
template <class F>
int max_right(F check, int L) {
assert(0 <= L && L <= n && check(Monoid::unit()));
if (L == n) return n;
L += size;
X sm = Monoid::unit();
do {
while (L % 2 == 0) L >>= 1;
if (!check(Monoid::op(sm, dat[L]))) {
while (L < size) {
L = 2 * L;
if (check(Monoid::op(sm, dat[L]))) { sm = Monoid::op(sm, dat[L++]); }
}
return L - size;
}
sm = Monoid::op(sm, dat[L++]);
} while ((L & -L) != L);
return n;
}
template <class F>
int min_left(F check, int R) {
assert(0 <= R && R <= n && check(Monoid::unit()));
if (R == 0) return 0;
R += size;
X sm = Monoid::unit();
do {
--R;
while (R > 1 && (R % 2)) R >>= 1;
if (!check(Monoid::op(dat[R], sm))) {
while (R < size) {
R = 2 * R + 1;
if (check(Monoid::op(dat[R], sm))) { sm = Monoid::op(dat[R--], sm); }
}
return R + 1 - size;
}
sm = Monoid::op(dat[R], sm);
} while ((R & -R) != R);
return 0;
}
// prod_{l<=i<r} A[i xor x]
X xor_prod(int l, int r, int xor_val) {
static_assert(Monoid::commute);
X x = Monoid::unit();
for (int k = 0; k < log + 1; ++k) {
if (l >= r) break;
if (l & 1) { x = Monoid::op(x, dat[(size >> k) + ((l++) ^ xor_val)]); }
if (r & 1) { x = Monoid::op(x, dat[(size >> k) + ((--r) ^ xor_val)]); }
l /= 2, r /= 2, xor_val /= 2;
}
return x;
}
};
#line 2 "/home/maspy/compro/library/alg/monoid/monoid_reverse.hpp"
template <class Monoid>
struct Monoid_Reverse {
using value_type = typename Monoid::value_type;
using X = value_type;
static constexpr X op(const X &x, const X &y) { return Monoid::op(y, x); }
static constexpr X unit() { return Monoid::unit(); }
static const bool commute = Monoid::commute;
};
#line 6 "/home/maspy/compro/library/graph/ds/tree_monoid.hpp"
template <typename TREE, typename Monoid, bool edge>
struct Tree_Monoid {
using MX = Monoid;
using X = typename MX::value_type;
TREE &tree;
int N;
SegTree<MX> seg;
SegTree<Monoid_Reverse<MX>> seg_r;
Tree_Monoid(TREE &tree) : tree(tree), N(tree.N) {
build([](int i) -> X { return MX::unit(); });
}
Tree_Monoid(TREE &tree, vc<X> &dat) : tree(tree), N(tree.N) {
build([&](int i) -> X { return dat[i]; });
}
template <typename F>
Tree_Monoid(TREE &tree, F f) : tree(tree), N(tree.N) {
build(f);
}
template <typename F>
void build(F f) {
if (!edge) {
auto f_v = [&](int i) -> X { return f(tree.V[i]); };
seg.build(N, f_v);
if constexpr (!MX::commute) { seg_r.build(N, f_v); }
} else {
auto f_e = [&](int i) -> X {
return (i == 0 ? MX::unit() : f(tree.v_to_e(tree.V[i])));
};
seg.build(N, f_e);
if constexpr (!MX::commute) { seg_r.build(N, f_e); }
}
}
void set(int i, X x) {
if constexpr (edge) i = tree.e_to_v(i);
i = tree.LID[i];
seg.set(i, x);
if constexpr (!MX::commute) seg_r.set(i, x);
}
void multiply(int i, X x) {
if constexpr (edge) i = tree.e_to_v(i);
i = tree.LID[i];
seg.multiply(i, x);
if constexpr (!MX::commute) seg_r.multiply(i, x);
}
X prod_path(int u, int v) {
auto pd = tree.get_path_decomposition(u, v, edge);
X val = MX::unit();
for (auto &&[a, b]: pd) { val = MX::op(val, get_prod(a, b)); }
return val;
}
// uv path 上で prod_path(u, x) が check を満たす最後の x
// なければ (つまり path(u,u) が ng )-1
template <class F>
int max_path(F check, int u, int v) {
if constexpr (edge) return max_path_edge(check, u, v);
if (!check(prod_path(u, u))) return -1;
auto pd = tree.get_path_decomposition(u, v, edge);
X val = MX::unit();
for (auto &&[a, b]: pd) {
X x = get_prod(a, b);
if (check(MX::op(val, x))) {
val = MX::op(val, x);
u = (tree.V[b]);
continue;
}
auto check_tmp = [&](X x) -> bool { return check(MX::op(val, x)); };
if (a <= b) {
// 下り
auto i = seg.max_right(check_tmp, a);
return (i == a ? u : tree.V[i - 1]);
} else {
// 上り
int i = 0;
if constexpr (MX::commute) i = seg.min_left(check_tmp, a + 1);
if constexpr (!MX::commute) i = seg_r.min_left(check_tmp, a + 1);
if (i == a + 1) return u;
return tree.V[i];
}
}
return v;
}
X prod_subtree(int u, int root = -1) {
if (root == u) return prod_all();
if (root == -1 || tree.in_subtree(u, root)) {
int l = tree.LID[u], r = tree.RID[u];
return seg.prod(l + edge, r);
}
assert(!edge); // さぼり
u = tree.jump(u, root, 1);
int L = tree.LID[u], R = tree.RID[u];
return MX::op(seg.prod(0, L), seg.prod(R, N));
}
X prod_all() { return prod_subtree(tree.V[0]); }
inline X get_prod(int a, int b) {
if constexpr (MX::commute) {
return (a <= b) ? seg.prod(a, b + 1) : seg.prod(b, a + 1);
}
return (a <= b) ? seg.prod(a, b + 1) : seg_r.prod(b, a + 1);
}
private:
template <class F>
int max_path_edge(F check, int u, int v) {
static_assert(edge);
if (!check(MX::unit())) return -1;
int lca = tree.lca(u, v);
auto pd = tree.get_path_decomposition(u, lca, edge);
X val = MX::unit();
// climb
for (auto &&[a, b]: pd) {
assert(a >= b);
X x = get_prod(a, b);
if (check(MX::op(val, x))) {
val = MX::op(val, x);
u = (tree.parent[tree.V[b]]);
continue;
}
auto check_tmp = [&](X x) -> bool { return check(MX::op(val, x)); };
int i = 0;
if constexpr (MX::commute) i = seg.min_left(check_tmp, a + 1);
if constexpr (!MX::commute) i = seg_r.min_left(check_tmp, a + 1);
if (i == a + 1) return u;
return tree.parent[tree.V[i]];
}
// down
pd = tree.get_path_decomposition(lca, v, edge);
for (auto &&[a, b]: pd) {
assert(a <= b);
X x = get_prod(a, b);
if (check(MX::op(val, x))) {
val = MX::op(val, x);
u = (tree.V[b]);
continue;
}
auto check_tmp = [&](X x) -> bool { return check(MX::op(val, x)); };
auto i = seg.max_right(check_tmp, a);
return (i == a ? u : tree.V[i - 1]);
}
return v;
}
};
#line 2 "/home/maspy/compro/library/ds/segtree/dual_segtree.hpp"
template <typename Monoid>
struct Dual_SegTree {
using MA = Monoid;
using A = typename MA::value_type;
int n, log, size;
vc<A> laz;
Dual_SegTree() : Dual_SegTree(0) {}
Dual_SegTree(int n) { build(n); }
void build(int m) {
n = m;
log = 1;
while ((1 << log) < n) ++log;
size = 1 << log;
laz.assign(size << 1, MA::unit());
}
A get(int p) {
assert(0 <= p && p < n);
p += size;
for (int i = log; i >= 1; i--) push(p >> i);
return laz[p];
}
vc<A> get_all() {
FOR(i, size) push(i);
return {laz.begin() + size, laz.begin() + size + n};
}
void set(int p, A x) {
get(p);
laz[p + size] = x;
}
void apply(int l, int r, const A& a) {
assert(0 <= l && l <= r && r <= n);
if (l == r) return;
l += size, r += size;
if (!MA::commute) {
for (int i = log; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
}
while (l < r) {
if (l & 1) all_apply(l++, a);
if (r & 1) all_apply(--r, a);
l >>= 1, r >>= 1;
}
}
private:
void push(int k) {
if (laz[k] == MA::unit()) return;
all_apply(2 * k, laz[k]), all_apply(2 * k + 1, laz[k]);
laz[k] = MA::unit();
}
void all_apply(int k, A a) { laz[k] = MA::op(laz[k], a); }
};
#line 3 "/home/maspy/compro/library/graph/ds/dual_tree_monoid.hpp"
template <typename TREE, typename Monoid, bool edge>
struct Dual_Tree_Monoid {
using MX = Monoid;
using X = typename MX::value_type;
TREE &tree;
int N;
Dual_SegTree<MX> seg;
Dual_Tree_Monoid(TREE &tree) : tree(tree), N(tree.N), seg(tree.N) {}
X get(int i) {
int v = i;
if (edge) {
auto &&e = tree.G.edges[i];
v = (tree.parent[e.frm] == e.to ? e.frm : e.to);
}
return seg.get(tree.LID[v]);
}
vc<X> get_all() {
vc<X> tmp = seg.get_all();
vc<X> res;
FOR(i, N) {
if (edge && i == N - 1) break;
int v = i;
if (edge) {
auto &&e = tree.G.edges[i];
v = (tree.parent[e.frm] == e.to ? e.frm : e.to);
}
res.eb(tmp[tree.LID[v]]);
}
return res;
}
void apply_path(int u, int v, X x) {
auto pd = tree.get_path_decomposition(u, v, edge);
for (auto &&[a, b]: pd) {
(a <= b ? seg.apply(a, b + 1, x) : seg.apply(b, a + 1, x));
}
return;
}
void apply_subtree(int u, X x) {
int l = tree.LID[u], r = tree.RID[u];
return seg.apply(l + edge, r, x);
}
void apply_outtree(int u, X a) {
int l = tree.LID[u], r = tree.RID[u];
seg.apply(0 + edge, l + edge, a);
seg.apply(r, N, a);
}
};
#line 2 "/home/maspy/compro/library/alg/monoid/min.hpp"
template <typename E>
struct Monoid_Min {
using X = E;
using value_type = X;
static constexpr X op(const X &x, const X &y) noexcept { return min(x, y); }
static constexpr X unit() { return infty<E>; }
static constexpr bool commute = true;
};
#line 2 "/home/maspy/compro/library/alg/monoid/max.hpp"
template <typename E>
struct Monoid_Max {
using X = E;
using value_type = X;
static constexpr X op(const X &x, const X &y) noexcept { return max(x, y); }
static constexpr X unit() { return -infty<E>; }
static constexpr bool commute = true;
};
#line 8 "/home/maspy/compro/library/graph/minimum_spanning_tree.hpp"
// return : {T mst_cost, vc<bool> in_mst, Graph MST}
template <typename T, typename GT>
tuple<T, vc<bool>, GT> minimum_spanning_tree(GT& G) {
int N = G.N;
int M = len(G.edges);
vc<int> I(M);
FOR(i, M) I[i] = i;
sort(all(I), [&](auto& a, auto& b) -> bool {
return (G.edges[a].cost) < (G.edges[b].cost);
});
vc<bool> in_mst(M);
UnionFind uf(N);
T mst_cost = T(0);
GT MST(N);
for (auto& i: I) {
auto& e = G.edges[i];
if (uf.merge(e.frm, e.to)) {
in_mst[i] = 1;
mst_cost += e.cost;
}
}
FOR(i, M) if (in_mst[i]) {
auto& e = G.edges[i];
MST.add(e.frm, e.to, e.cost);
}
MST.build();
return {mst_cost, in_mst, MST};
}
// https://codeforces.com/contest/828/problem/F
// return : {T mst_cost, vc<bool> in_mst, Graph MST, vc<T> dat}
// dat : 辺ごとに、他の辺を保ったときに MST 辺になる最大重み
template <typename T, typename GT>
tuple<T, vc<bool>, GT, vc<T>> minimum_spanning_tree_cycle_data(GT& G) {
int M = len(G.edges);
auto [mst_cost, in_mst, MST] = minimum_spanning_tree(G);
Tree<GT> tree(MST);
vc<T> dat;
FOR(i, M) if (in_mst[i]) dat.eb(G.edges[i].cost);
Tree_Monoid<decltype(tree), Monoid_Max<T>, 1> TM1(tree, dat);
Dual_Tree_Monoid<decltype(tree), Monoid_Min<T>, 1> TM2(tree);
FOR(i, M) {
if (!in_mst[i]) {
auto& e = G.edges[i];
TM2.apply_path(e.frm, e.to, e.cost);
}
}
vc<T> ANS(M);
int m = 0;
FOR(i, M) {
auto& e = G.edges[i];
if (in_mst[i])
ANS[i] = TM2.get(m++);
else
ANS[i] = TM1.prod_path(e.frm, e.to);
}
return {mst_cost, in_mst, MST, ANS};
}
#line 5 "main.cpp"
void solve() {
LL(N, M);
Graph<int, 0> G(N);
G.read_graph(M, 1);
ll ANS = get<0>(minimum_spanning_tree<ll>(G));
print(ANS);
}
signed main() { solve(); }
詳細信息
Pretests
Final Tests
Test #1:
score: 10
Accepted
time: 0ms
memory: 3960kb
input:
1 0
output:
0
result:
ok answer is '0'
Test #2:
score: 10
Accepted
time: 69ms
memory: 29076kb
input:
1 500000 1 1 436085873 1 1 289134331 1 1 95168426 1 1 809912668 1 1 912905316 1 1 51427205 1 1 808052925 1 1 168547991 1 1 469573116 1 1 7523372 1 1 700424384 1 1 329491017 1 1 886380039 1 1 92596215 1 1 870407506 1 1 420928567 1 1 29439913 1 1 851970613 1 1 595343843 1 1 150074451 1 1 981248098 1 1...
output:
0
result:
ok answer is '0'
Test #3:
score: 10
Accepted
time: 0ms
memory: 3860kb
input:
1049 1095 37 1027 185663189 439 923 842401821 92 68 172561838 108 320 929023969 537 284 451497914 161 836 18296000 101 14 582350247 82 947 633276668 555 731 321285985 282 946 133823187 549 982 59411620 19 151 982845654 961 22 185979994 201 958 42654715 178 446 121754463 100 386 87537747 492 486 2228...
output:
459312924580
result:
ok answer is '459312924580'
Test #4:
score: 10
Accepted
time: 73ms
memory: 29148kb
input:
1677 500000 1010 1055 334171722 32 548 496908773 1662 273 215127528 1596 969 799111789 993 895 816193284 335 56 975688725 1537 1674 694838017 512 1006 84989138 487 1094 77423013 1131 522 260247889 32 1581 652804125 1472 1609 861174323 1083 230 236457705 1009 593 692730522 709 284 647880265 936 1598 ...
output:
3426870407
result:
ok answer is '3426870407'
Test #5:
score: 10
Accepted
time: 72ms
memory: 29352kb
input:
4782 500000 401 2704 143282494 408 742 221495274 2487 2740 328112333 1471 3347 678117943 2369 3844 94084087 4137 629 771103 1506 2976 377332399 3856 3529 15354521 977 1747 267860558 2561 1837 234002816 1947 1191 447985398 2575 3486 210906740 321 1319 879712756 3660 3019 926744290 4492 528 110850246 ...
output:
20391912348
result:
ok answer is '20391912348'
Test #6:
score: 10
Accepted
time: 47ms
memory: 26996kb
input:
100000 250000 11249 63248 716981925 77587 45081 715237577 40869 43888 384028427 68447 21259 718879057 15416 4835 542698454 86984 39250 200243926 38485 9822 321829618 68650 80338 208779180 93995 71720 970100731 62306 65602 758670337 12962 93202 405549936 11239 70788 481995017 65169 11656 137255256 93...
output:
19768912676568
result:
ok answer is '19768912676568'
Test #7:
score: 10
Accepted
time: 53ms
memory: 27100kb
input:
100000 250000 58087 98694 276928916 81020 20563 474360924 54330 72482 965233532 69316 62625 693679792 68391 25019 626212979 66635 9065 208396713 18722 31967 29636156 18804 17430 126344131 52091 61058 813889563 22524 92717 616323226 91592 59352 7003125 39568 15009 745751969 59457 33731 34864625 3185 ...
output:
19671766809300
result:
ok answer is '19671766809300'
Test #8:
score: 10
Accepted
time: 47ms
memory: 35404kb
input:
200000 199999 65210 94695 20344717 27677 60426 947830254 44160 166001 68537440 144553 10242 174779136 72796 113802 266364597 1858 24797 628448494 194099 76945 666582594 133683 17237 128244232 152149 91422 110103130 150169 10041 739399998 136455 75250 7894691 81174 102926 26871471 27780 63438 7883747...
output:
94124014988825
result:
ok answer is '94124014988825'
Test #9:
score: 10
Accepted
time: 102ms
memory: 51804kb
input:
200000 500000 46671 50310 339946279 111950 44341 976219244 183028 30375 283623377 119684 483 278812425 123223 173434 86847632 53396 67926 343986583 195715 85791 872435965 51759 67385 324694963 132645 146330 74109089 142363 58800 508205119 151247 105471 160455427 97528 133772 68416120 33125 33151 102...
output:
39818560453301
result:
ok answer is '39818560453301'
Test #10:
score: 10
Accepted
time: 98ms
memory: 50820kb
input:
200000 500000 45588 17449 500297001 167443 90625 840063438 184162 31916 123322602 75130 105595 80124915 4990 23835 842648585 198193 138933 377398791 61179 68315 899014505 170138 8312 214877618 130847 183955 648135341 186493 178082 135732043 34104 128022 298311436 180739 90096 241294500 90919 4640 35...
output:
39679281240808
result:
ok answer is '39679281240808'