Submission #265049

#TimeUsernameProblemLanguageResultExecution timeMemory
265049KoDBridges (APIO19_bridges)C++11
100 / 100
2818 ms8184 KiB
#include <iostream> #include <algorithm> #include <utility> #include <cstdint> #include <cstddef> #include <vector> #include <array> #include <stack> #include <tuple> #include <cstring> namespace fast_io { static constexpr size_t buf_size = 1 << 18; static constexpr size_t buf_margin = 1; static constexpr size_t block_size = 10000; static constexpr size_t integer_size = 20; static char inbuf[buf_size + buf_margin] = {}; static char outbuf[buf_size + buf_margin] = {}; static char block_str[block_size * 4 + buf_margin] = {}; static constexpr uint64_t power10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000, 10000000000000000000u }; class scanner { private: size_t M_in_pos = 0, M_in_end = buf_size; void M_load() { M_in_end = fread(inbuf, 1, buf_size, stdin); inbuf[M_in_end] = '\0'; } void M_reload() { size_t length = M_in_end - M_in_pos; memmove(inbuf, inbuf + M_in_pos, length); M_in_end = length + fread(inbuf + length, 1, buf_size - length, stdin); inbuf[M_in_end] = '\0'; M_in_pos = 0; } void M_ignore_space() { while (inbuf[M_in_pos] <= ' ') { if (__builtin_expect(++M_in_pos == M_in_end, 0)) M_reload(); } } char M_next() { return inbuf[M_in_pos++]; } char M_next_nonspace() { M_ignore_space(); return inbuf[M_in_pos++]; } public: scanner() { M_load(); } void scan(char &c) { c = M_next_nonspace(); } void scan(std::string &s) { M_ignore_space(); s = ""; do { size_t start = M_in_pos; while (inbuf[M_in_pos] > ' ') ++M_in_pos; s += std::string(inbuf + start, inbuf + M_in_pos); if (inbuf[M_in_pos] != '\0') break; M_reload(); } while (true); } template <class T> typename std::enable_if<std::is_integral<T>::value, void>::type scan(T &x) { char c = M_next_nonspace(); if (__builtin_expect(M_in_pos + integer_size >= M_in_end, 0)) M_reload(); bool n = false; if (c == '-') n = true, x = 0; else x = c & 15; while ((c = M_next()) >= '0') x = x * 10 + (c & 15); if (n) x = -x; } template <class T, class... Args> void scan(T &x, Args&... args) { scan(x); scan(args...); } template <class T> scanner& operator >> (T &x) { scan(x); return *this; } }; class printer { private: size_t M_out_pos = 0; void M_flush() { fwrite(outbuf, 1, M_out_pos, stdout); M_out_pos = 0; } void M_precompute() { for (size_t i = 0; i < block_size; ++i) { size_t j = 4, k = i; while (j--) { block_str[i * 4 + j] = k % 10 + '0'; k /= 10; } } } static size_t S_integer_digits(uint64_t n) { if (n >= power10[10]) { if (n >= power10[19]) return 20; if (n >= power10[18]) return 19; if (n >= power10[17]) return 18; if (n >= power10[16]) return 17; if (n >= power10[15]) return 16; if (n >= power10[14]) return 15; if (n >= power10[13]) return 14; if (n >= power10[12]) return 13; if (n >= power10[11]) return 12; return 11; } else { if (n >= power10[9]) return 10; if (n >= power10[8]) return 9; if (n >= power10[7]) return 8; if (n >= power10[6]) return 7; if (n >= power10[5]) return 6; if (n >= power10[4]) return 5; if (n >= power10[3]) return 4; if (n >= power10[2]) return 3; if (n >= power10[1]) return 2; return 1; } } public: printer() { M_precompute(); } ~printer() { M_flush(); } void print(char c) { outbuf[M_out_pos++] = c; if (__builtin_expect(M_out_pos == buf_size, 0)) M_flush(); } void print(const char *s) { while (*s != 0) { outbuf[M_out_pos++] = *s++; if (M_out_pos == buf_size) M_flush(); } } void print(const std::string &s) { for (auto c: s) { outbuf[M_out_pos++] = c; if (M_out_pos == buf_size) M_flush(); } } template <class T> typename std::enable_if<std::is_integral<T>::value, void>::type print(T x) { if (__builtin_expect(M_out_pos + integer_size >= buf_size, 0)) M_flush(); if (x < 0) print('-'), x = -x; size_t digit = S_integer_digits(x); size_t len = digit; while (len >= 4) { len -= 4; memcpy(outbuf + M_out_pos + len, block_str + (x % block_size) * 4, 4); x /= 10000; } memcpy(outbuf + M_out_pos, block_str + x * 4 + 4 - len, len); M_out_pos += digit; } template <class T, class... Args> void print(const T &x, const Args&... args) { print(x); print(' '); print(args...); } template <class... Args> void println(const Args&... args) { print(args...); print('\n'); } template <class T> printer& operator << (const T &x) { print(x); return *this; } }; }; /** * @title Fast Input/Output */ fast_io::scanner in; fast_io::printer out; using i32 = int32_t; using i64 = int64_t; using u32 = uint32_t; using u64 = uint64_t; constexpr i32 inf32 = (i32(1) << 30) - 1; constexpr i64 inf64 = (i64(1) << 62) - 1; constexpr size_t BUCKET = 800; constexpr size_t VERTICES = 50000; constexpr size_t EDGES = 100000; constexpr size_t QUERIES = 100000; size_t N, M, Q, Step; std::array<i32, VERTICES> parent; std::array<i32, EDGES> U, V, C; std::array<bool, EDGES> Static; struct Query { i32 type, idx, weight; }; std::array<Query, QUERIES> Qs; std::vector<i32> static_query, dynamic_query; std::array<i32, QUERIES> answer; i32 find(i32 u) { while (parent[u] >= 0) { u = parent[u]; } return u; } void merge(i32 u, i32 v) { u = find(u); v = find(v); if (u == v) { return; } if (parent[u] > parent[v]) { std::swap(u, v); } parent[u] += parent[v]; parent[v] = u; } int main() { in.scan(N, M); for (size_t i = 0; i < M; ++i) { in.scan(U[i], V[i], C[i]); --U[i]; --V[i]; } in.scan(Q); Step = (Q + BUCKET - 1) / BUCKET; for (size_t i = 0; i < Q; ++i) { in.scan(Qs[i].type, Qs[i].idx, Qs[i].weight); --Qs[i].idx; } std::fill(Static.begin(), Static.end(), true); static_query.reserve(M + BUCKET); dynamic_query.reserve(BUCKET); for (size_t step = 0; step < Step; ++step) { std::fill(parent.begin(), parent.begin() + N, -1); const size_t first = step * BUCKET; const size_t last = std::min((step + 1) * BUCKET, Q); for (size_t i = first; i < last; ++i) { if (Qs[i].type == 1) { Static[Qs[i].idx] = false; dynamic_query.push_back((i32) i); } else { static_query.push_back(-((i32) i + 1)); } } for (size_t i = 0; i < M; ++i) { if (Static[i]) { static_query.push_back((i32) i); } } std::sort(static_query.begin(), static_query.end(), [](i32 i, i32 j) { if (i >= 0 && j >= 0) { return C[i] > C[j]; } else if (i >= 0) { if (C[i] == Qs[-(j + 1)].weight) { return true; } return C[i] > Qs[-(j + 1)].weight; } else if (j >= 0) { if (Qs[-(i + 1)].weight == C[j]) { return false; } return Qs[-(i + 1)].weight > C[j]; } else { return Qs[-(i + 1)].weight > Qs[-(j + 1)].weight; } }); for (auto i: static_query) { if (i >= 0) { merge(U[i], V[i]); } else { i = -(i + 1); std::stack<std::pair<i32, i32>> fix_edges; for (auto j: dynamic_query) { if (j > i) { break; } fix_edges.emplace(Qs[j].idx, C[Qs[j].idx]); C[Qs[j].idx] = Qs[j].weight; } std::stack<std::tuple<i32, i32, i32, i32>> fix_nodes; for (auto j: dynamic_query) { if (C[Qs[j].idx] < Qs[i].weight) { continue; } i32 u = find(U[Qs[j].idx]); i32 v = find(V[Qs[j].idx]); if (u == v) { continue; } if (parent[u] > parent[v]) { std::swap(u, v); } fix_nodes.emplace(u, parent[u], v, parent[v]); parent[u] += parent[v]; parent[v] = u; } answer[i] = -parent[find(Qs[i].idx)]; while (!fix_edges.empty()) { C[fix_edges.top().first] = fix_edges.top().second; fix_edges.pop(); } while (!fix_nodes.empty()) { const auto &top = fix_nodes.top(); parent[std::get<0>(top)] = std::get<1>(top); parent[std::get<2>(top)] = std::get<3>(top); fix_nodes.pop(); } } } for (size_t i = first; i < last; ++i) { if (Qs[i].type == 1) { C[Qs[i].idx] = Qs[i].weight; Static[Qs[i].idx] = true; } } static_query.clear(); dynamic_query.clear(); } for (auto x: answer) { if (x != 0) { out.println(x); } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...