제출 #317498

#제출 시각아이디문제언어결과실행 시간메모리
317498Plasmatic다리 (APIO19_bridges)C++11
100 / 100
2769 ms13560 KiB
// ./apio-19-p2-bridges.yml #include "bits/stdc++.h" using namespace std; // Defines #define fs first #define sn second #define pb push_back #define eb emplace_back #define mpr make_pair #define mtp make_tuple #define all(x) (x).begin(), (x).end() // Basic type definitions using ll = long long; using ull = unsigned long long; using ld = long double; using pii = pair<int, int>; using pll = pair<long long, long long>; // PBDS order statistic tree #include <ext/pb_ds/assoc_container.hpp> // Common file #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; template <typename T, class comp = less<T>> using os_tree = tree<T, null_type, comp, rb_tree_tag, tree_order_statistics_node_update>; template <typename K, typename V, class comp = less<K>> using treemap = tree<K, V, comp, rb_tree_tag, tree_order_statistics_node_update>; // HashSet #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; const ll RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count(); struct chash { ll operator()(ll x) const { return x ^ RANDOM; } }; template <typename T, class Hash> using hashset = gp_hash_table<T, null_type, Hash>; template <typename K, typename V, class Hash> using hashmap = gp_hash_table<K, V, Hash>; // More utilities int SZ(string &v) { return v.length(); } template <typename C> int SZ(C &v) { return v.size(); } template <typename C> void UNIQUE(vector<C> &v) { sort(v.begin(), v.end()); v.resize(unique(v.begin(), v.end()) - v.begin()); } template <typename T, typename U> void maxa(T &a, U b) { a = max(a, b); } template <typename T, typename U> void mina(T &a, U b) { a = min(a, b); } const ll INF = 0x3f3f3f3f, LLINF = 0x3f3f3f3f3f3f3f3f; struct query { int a, b, i; bool operator<(const query &o) const { return b > o.b; } }; struct edge { int a, b, c, i, qo; bool operator<(const edge &o) const { return c < o.c; } }; bool cmpi(const edge a, const edge b) { return a.qo > b.qo; } ostream& operator<<(ostream& out, const query o) { out << "(a=" << o.a << ", b=" << o.b << ", i=" << o.i << ")"; return out; } ostream& operator<<(ostream& out, const edge o) { out << "(a=" << o.a << ", b=" << o.b << ", c=" << o.c << ", i=" << o.i << ", qo=" << o.qo << ")"; return out; } struct gedge { int c, i; bool operator<(const gedge &o) const { return c == o.c ? i < o.i : c > o.c; } }; const int MN = 5e4 + 1, MQ = 1e5 + 1, BSZ = 2*317; // const int MN = 5e4 + 1, MQ = 1e5 + 1, BSZ = 4; int N, M, Q; set<gedge> edges; struct DSU { int dsu[MN], sz[MN]; void init(int N) { iota(dsu, dsu + N + 1, 0); fill(sz, sz + N + 1, 1); } int rt(int x) { return dsu[x] == x ? x : dsu[x] = rt(dsu[x]); } void merge(int x, int y) { // x -> y x = rt(x); y = rt(y); if (x == y) return; if (sz[y] > sz[x]) swap(x, y); sz[x] += sz[y]; dsu[y] = x; } int getsz(int x) { return sz[rt(x)]; } bool same(int x, int y) { return rt(x) == rt(y); } }; int W[MQ], A[MQ], B[MQ], ans[MQ]; bool rem[MQ]; DSU dsu; // per query bool cuse[MQ], vis[MN]; vector<int> found, tmpg[MN]; int stk[MN], spt = 0; int dfs(int c) { int res = 0; stk[spt++] = c; vis[c] = true; while (spt) { int c = stk[--spt]; res += dsu.sz[c]; // cout<<"[dfs]: "; cout<<"c="<<(c)<<", "; cout<<"dsu.sz[c]="<<(dsu.sz[c])<<", "; cout << endl; // db l:dfs,c,dsu.sz[c] found.pb(c); for (int to : tmpg[c]) { if (!vis[to]) { vis[to] = true; stk[spt++] = to; } } } return res; } // for block vector<query> qs; vector<edge> uedges; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> (N) >> (M); for (auto i = 1; i <= M; i++) { int a, b, c; cin >> a >> b >> c; edges.insert({c, i}); W[i] = c; A[i] = a; B[i] = b; } cin >> (Q); for (auto i = 0; i < Q; i += BSZ) { // collect queries for (auto j = i; j < min(Q, i + BSZ); j++) { int t, a, b; cin >> t >> a >> b; if (t == 1) { uedges.pb({A[a], B[a], b, a, j}); if (!rem[a] && b < W[a]) { uedges.pb({A[a], B[a], W[a], a, -INF}); rem[a] = true; } } else if (t == 2) qs.pb({a, b, j}); } sort(all(qs)); sort(all(uedges), cmpi); // cout << "qs=["; for (auto __x:qs)cout<<__x<<", "; cout<<"], "; cout << endl; // db I:qs // cout << "uedges=["; for (auto __x:uedges)cout<<__x<<", "; cout<<"], "; cout << endl; // db I:uedges // solve queries dsu.init(N); auto ptr = edges.begin(); for (auto &q : qs) { while (ptr != edges.end() && (rem[ptr->i] || ptr->c >= q.b)) { if (!rem[ptr->i]) dsu.merge(A[ptr->i], B[ptr->i]); ptr++; } // cout<<"[q]: "; cout<<"q="<<(q)<<", "; cout << endl; // db l:q,q // build graph man for (auto &e : uedges) { if (!cuse[e.i] && e.qo < q.i) { cuse[e.i] = true; if (e.c >= q.b) { // cout<<"[use]: "; cout<<"e="<<(e)<<", "; cout << endl; // db l:use,e int a = dsu.rt(e.a), b = dsu.rt(e.b); if (a != b) { tmpg[a].pb(b); tmpg[b].pb(a); } } } } // bruh int cans = dfs(dsu.rt(q.a)); ans[q.i] = cans; // cleanup per query for (auto &e : uedges) { if (cuse[e.i]) { cuse[e.i] = false; tmpg[dsu.rt(e.a)].clear(); tmpg[dsu.rt(e.b)].clear(); } } for (auto &x : found) vis[x] = false; found.clear(); } // undo and reset DS for (auto it = uedges.rbegin(); it != uedges.rend(); it++) { auto &e = *it; if (W[e.i] != e.c) { edges.erase(edges.find({W[e.i], e.i})); W[e.i] = e.c; edges.insert({W[e.i], e.i}); } rem[e.i] = false; } qs.clear(); uedges.clear(); } for (auto i = 0; i < Q; i++) if (ans[i]) cout << (ans[i]) << '\n'; 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...