제출 #699784

#제출 시각아이디문제언어결과실행 시간메모리
699784badont다리 (APIO19_bridges)C++17
100 / 100
2256 ms18948 KiB
#include <iostream> #include <vector> #include <algorithm> #include <cassert> #include <cmath> #include <utility> #include <array> #include <numeric> #include <list> #include <iomanip> using namespace std; template<typename T, typename = void> struct is_iterable : false_type {}; template<typename T> struct is_iterable<T, void_t<decltype(begin(declval<T>())),decltype(end(declval<T>()))>> : true_type {}; template<typename T> typename enable_if<is_iterable<T>::value&&!is_same<T, string>::value,ostream&>::type operator<<(ostream &cout, T const &v); template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; } template<typename T> typename enable_if<is_iterable<T>::value&&!is_same<T, string>::value,ostream&>::type operator<<(ostream &cout, T const &v) { cout << "["; for (auto it = v.begin(); it != v.end();) { cout << *it; if (++it != v.end()) cout << ", "; } return cout << "]"; } void dbg_out() { cout << endl; } template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); } #ifdef LOCAL #define debug(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define debug(...) "zzz" #endif #define all(x) x.begin(),x.end() #define pb push_back #define sz(x) (int)x.size() using ll = long long; using pii = pair<ll,ll>; using ld = long double; using vi = vector<int>; struct RollbackUF { vi e; vector<pii> st; RollbackUF(int n) : e(n, -1) {} int size(int x) { return -e[find(x)]; } int find(int x) { return e[x] < 0 ? x : find(e[x]); } int time() { return sz(st); } void rollback(int t) { for (int i = time(); i --> t;) e[st[i].first] = st[i].second; st.resize(t); } bool join(int a, int b) { a = find(a), b = find(b); if (a == b) return false; if (e[a] > e[b]) swap(a, b); st.push_back({a, e[a]}); st.push_back({b, e[b]}); e[a] += e[b]; e[b] = a; return true; } }; void solve() { ll n, m; cin >> n >> m; vector<array<ll, 3>> edges(m); for (auto& [x, y, d] : edges) { cin >> x >> y >> d; x--; y--; d = -d; } ll q; cin >> q; const int B = 1000; vector<array<ll, 3>> queries_input(q); for (auto& [T, b, r] : queries_input) { cin >> T >> b >> r; b--; r = -r; } const vector queries = queries_input; vector<ll> ans(q, -1); vector<bool> visited_query(q, false); for (ll qid = 0; qid < q; qid += B) { vector<int> process; vector<bool> changed_edges(m, false); vector<int> change_list; vector change_times(m, vector<ll>()); for (ll i = qid; i < min(qid + B, q); i++) { process.emplace_back(i); visited_query[i] = true; } for (auto query_idx : process) { auto [type, r, b] = queries[query_idx]; if (type == 1) { changed_edges[r] = true; change_times[r].pb(query_idx); change_list.pb(r); } } sort(all(change_list)); change_list.erase(unique(all(change_list)), change_list.end()); vector<int> unchanged_indices; for (int i = 0; i < m; i++) if (!changed_edges[i]) { unchanged_indices.pb(i); } sort(all(unchanged_indices), [&](int a, int b) { return edges[a][2] < edges[b][2]; }); debug(unchanged_indices); //must process all edges in --> increasing order sort(all(process), [&](int a, int b) { //if (queries[a][2] == queries[b][2]) return queries[a][0] < queries[b][0]; return queries[a][2] < queries[b][2]; }); debug(process); auto get_weight = [&](int unchanged_index) -> ll { return edges[unchanged_indices[unchanged_index]][2]; }; int unchanged_ptr = 0; RollbackUF dsu(n); for (int i = 0; i < process.size(); i++) { int u = process[i]; auto [T, r, b] = queries[u]; while (unchanged_ptr < (int)unchanged_indices.size() and get_weight(unchanged_ptr) <= b) { auto [e1, e2, w1] = edges[unchanged_indices[unchanged_ptr]]; assert(w1 <= b); dsu.join(e1, e2); unchanged_ptr++; } int rollback_time = dsu.time(); if (T == 1) { } else { for (auto edge_num : change_list) { assert(edge_num >= 0 and edge_num < m); auto [p1, p2, original_weight] = edges[edge_num]; ll max_less = -1; for (auto query_idx : change_times[edge_num]) if (query_idx < u) { max_less = max(max_less, query_idx); } if (max_less != -1) { auto [T2, edge_point, new_weight] = queries[max_less]; assert(T2 == 1 and edge_point == edge_num and max_less < u); if (new_weight <= b) dsu.join(p1, p2); } else { if (original_weight <= b) dsu.join(p1, p2); } } ans[u] = dsu.size(r); } dsu.rollback(rollback_time); } //update edges to be relevant sort(all(process)); for (auto query_idx : process) { auto [type, b, r] = queries[query_idx]; assert(r < 0); if (type == 1) { edges[b][2] = r; } } } for (int i = 0; i < q; i++) { int u = ans[i]; assert(visited_query[i]); if (queries[i][0] == 2) assert(u != -1); if (u != -1) { assert(queries[i][0] == 2); //assert(u < n); cout << u << '\n'; } } } int main() { cin.tie(0)->sync_with_stdio(0); solve(); return 0; }

컴파일 시 표준 에러 (stderr) 메시지

bridges.cpp: In function 'void solve()':
bridges.cpp:31:20: warning: statement has no effect [-Wunused-value]
   31 | #define debug(...) "zzz"
      |                    ^~~~~
bridges.cpp:120:9: note: in expansion of macro 'debug'
  120 |         debug(unchanged_indices);
      |         ^~~~~
bridges.cpp:31:20: warning: statement has no effect [-Wunused-value]
   31 | #define debug(...) "zzz"
      |                    ^~~~~
bridges.cpp:128:9: note: in expansion of macro 'debug'
  128 |         debug(process);
      |         ^~~~~
bridges.cpp:136:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  136 |         for (int i = 0; i < process.size(); i++) {
      |                         ~~^~~~~~~~~~~~~~~~
#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...