제출 #699783

#제출 시각아이디문제언어결과실행 시간메모리
699783badont다리 (APIO19_bridges)C++17
14 / 100
1704 ms15100 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
        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...