Submission #1126849

#TimeUsernameProblemLanguageResultExecution timeMemory
1126849Mikael639Bridges (APIO19_bridges)C++20
59 / 100
3111 ms517964 KiB
#include <bits/stdc++.h> #define fi first #define se second #define For(i, a, b) for (int i = (a); i <= (b); ++i) #define ForD(i, a, b) for (int i = (a); i >= (b); --i) #define rep(i, n) for (int i = 0; i < (n); ++i) #define repD(i, n) for (int i = (n) - 1; i >= 0; --i) #define coutE(x) {cout << x << '\n'; return;} #define pb push_back #define pf push_front #define all(x) x.begin(), x.end() #define sz(x) (int)x.size() #define bs binary_search #define ub upper_bound #define lb lower_bound #define endl '\n' #define db long double #define ll long long #define ii pair<int, int> #define vi vector<int> #define vii vector<ii> #define int long long using namespace std; void file(string s){ if (s.empty()) return; freopen((s + ".inp").c_str(), "r", stdin); freopen((s + ".out").c_str(), "w", stdout); } template <class X, class Y> bool minimize(X &x, Y y){ if (x > y){ x = y; return 1; } return 0; } template <class X, class Y> bool maximize(X &x, Y y){ if (x < y){ x = y; return 1; } return 0; } mt19937_64 rng(time(0)); const int N = 1e5 + 5; const int B = 400; int n, m, q; struct edge{ int u, v, w; } ed[N]; struct query{ int t, x, w; } quer[N]; bool bad[N]; int ans[N]; vi g[N]; int par[N]; stack<pair<int&, int>> history; int find(int u){ while (par[u] > 0) u = par[u]; return u; } void rollBack(int t){ while (sz(history) > t){ history.top().fi = history.top().se; history.pop(); } } void Union(edge e){ int u = find(e.u), v = find(e.v); if (u == v) return; if (par[u] > par[v]) swap(u, v); history.push({par[u], par[u]}); history.push({par[v], par[v]}); par[u] += par[v]; par[v] = u; } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; For(i, 1, m){ cin >> ed[i].u >> ed[i].v >> ed[i].w; } cin >> q; For(i, 1, q){ cin >> quer[i].t >> quer[i].x >> quer[i].w; } for (int l = 1; l <= q; l += B){ memset(par, -1, sizeof par); int r = min(q, l + B - 1); vi ask, changed, unchanged; For(i, l, r){ if (quer[i].t == 1){ //change is bad bad[quer[i].x] = 1; //remember that edge's id not query's id } else{ ask.pb(i); } } For(i, 1, m){ if (bad[i]) changed.pb(i); else unchanged.pb(i); //remember to reset bad[i] = 0; } //O(B^2) For(i, l, r){ if (quer[i].t == 1){ //update new weight ed[quer[i].x].w = quer[i].w; } else{ for (int j: changed){ if (ed[j].w >= quer[i].w){ //g[i] saves bad edges that i needs g[i].pb(j); } } } } sort(all(ask), [&](int i, int j){ return quer[i].w > quer[j].w; }); sort(all(unchanged), [&](int i, int j){ return ed[i].w > ed[j].w; }); int pnt = 0; //O(B * (m + B)) for (int i: ask){ while (pnt < sz(unchanged) && ed[unchanged[pnt]].w >= quer[i].w) Union(ed[unchanged[pnt++]]); int last = sz(history); for (int j: g[i]) Union(ed[j]); ans[i] = -par[find(quer[i].x)]; rollBack(last); //O(B) g[i].clear(); } } For(i, 1, q) if (quer[i].t == 2) cout << ans[i] << endl; return 0; }

Compilation message (stderr)

bridges.cpp: In function 'void file(std::string)':
bridges.cpp:37:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   37 |     freopen((s + ".inp").c_str(), "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bridges.cpp:38:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   38 |     freopen((s + ".out").c_str(), "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...