Submission #1127607

#TimeUsernameProblemLanguageResultExecution timeMemory
1127607InvMODBridges (APIO19_bridges)C++20
100 / 100
2119 ms9076 KiB
#include <bits/stdc++.h> using namespace std; #define fi first #define se second #define gcd __gcd #define sz(v) (int) v.size() #define pb push_back #define pi pair<int,int> #define all(v) (v).begin(), (v).end() #define compact(v) (v).erase(unique(all(v)), (v).end()) #define FOR(i, a, b) for(int i = (a); i <= (b); i++) #define REV(i, a, b) for(int i = (a); i >= (b); i--) #define dbg(x) "[" #x " = " << (x) << "]" ///#define int long long using ll = long long; using ld = long double; using ull = unsigned long long; template<typename T> bool ckmx(T& a, const T& b){if(a < b) return a = b, true; return false;} template<typename T> bool ckmn(T& a, const T& b){if(a > b) return a = b, true; return false;} struct DSU{ vector<int> par,sz; vector<pair<int&, int>> state; DSU(int n = 0): par(n + 1) { sz.resize(n + 1); for(int i = 1; i <= n; i++){ par[i] = i; sz[i] = 1; } return; } int f(int x){ return x == par[x] ? x : f(par[x]); } bool join(int u, int v){ u = f(u), v = f(v); if(u == v) return false; if(sz[u] < sz[v]) swap(u, v); state.pb({sz[u], sz[u]}); state.pb({par[v], par[v]}); par[v] = u; sz[u] += sz[v]; return true; } int snap(){ return sz(state); } int gsz(int x){ return sz[f(x)]; } void rollback(int time){ while(snap() > time){ assert(sz(state) > 0); state.back().fi = state.back().se; state.pop_back(); } return; } }; const int N = 1e5+5; const int B = 800; struct Edge{ int u,v,w; Edge(int u = 0, int v = 0, int w = 0): u(u), v(v), w(w) {} bool operator < (const Edge& q) const{ return (w == q.w ? (v > q.v) : (w > q.w)); } }; struct Query{ int op,v,w; Query(int op = 0, int v = 0, int w = 0): op(op), v(v), w(w) {} }; int n, m, q, answer[N]; int nxtQ[N]; bool inBlock[N], changeUpd[N]; Edge E[N]; Query Q[N]; void solveBlock(int idBlock){ int lBlock = (idBlock - 1) * B + 1; int rBlock = min(q, idBlock * B); vector<Edge> Eblock; vector<int> saveUpd, saveEdge; for(int i = lBlock; i <= rBlock; i++){ if(Q[i].op & 1){ saveUpd.push_back(i); inBlock[Q[i].v] = true; } else{ Eblock.push_back(Edge(i, -1, Q[i].w)); } } for(int i = 1; i <= m; i++){ if(!inBlock[i]) Eblock.push_back(E[i]); else{ saveEdge.push_back(i); } } sort(all(Eblock)); DSU dsu(n); for(int i = 0; i < sz(Eblock); i++){ if(Eblock[i].v == -1){ // Query int cur_Qid = Eblock[i].u, snap = dsu.snap(); for(int j = 0; j < sz(saveUpd); j++){ int id = saveUpd[j]; if(id <= cur_Qid && nxtQ[id] > cur_Qid){ int idEdge = Q[id].v; if(!changeUpd[idEdge]){ changeUpd[idEdge] = true; } if(Q[id].w >= Q[cur_Qid].w){ int u = E[idEdge].u, v = E[idEdge].v; dsu.join(u, v); } } } for(int j = 0; j < sz(saveEdge); j++){ if(!changeUpd[saveEdge[j]]){ if(E[saveEdge[j]].w >= Q[cur_Qid].w){ int u = E[saveEdge[j]].u; int v = E[saveEdge[j]].v; dsu.join(u, v); } } else changeUpd[saveEdge[j]] = false; } answer[cur_Qid] = dsu.gsz(Q[cur_Qid].v); dsu.rollback(snap); } else{ // Normal Update int u = Eblock[i].u, v = Eblock[i].v; dsu.join(u, v); } } for(int i = lBlock; i <= rBlock; i++){ if(Q[i].op & 1){ int idEdge = Q[i].v; E[idEdge].w = Q[i].w; inBlock[idEdge] = false; } } return; } void preprocess() { vector<int> nxt(m + 1, q + 1); for(int i = q; i >= 1; i--){ if(Q[i].op & 1){ int id = Q[i].v; nxtQ[i] = nxt[id]; nxt[id] = i; } } return; } void solve() { cin >> n >> m; for(int i = 1; i <= m; i++){ int u,v,w; cin >> u >> v >> w; E[i] = Edge(u, v, w); } cin >> q; for(int i = 1; i <= q; ++i){ int op,id,w; cin >> op >> id >> w; Q[i] = Query(op, id, w); } preprocess(); int qblock = (q + B - 1) / B; for(int i = 1; i <= qblock; i++){ solveBlock(i); } for(int i = 1; i <= q; i++){ if(Q[i].op % 2 == 0) cout << answer[i] << "\n"; } return; } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define name "InvMOD" if(fopen(name".INP", "r")){ freopen(name".INP","r",stdin); freopen(name".OUT","w",stdout); } int t = 1; //cin >> t; while(t--) solve(); return 0; } /* Debug Test 5 10 1 2 7 1 3 6 1 4 6 1 5 6 2 3 6 2 4 5 2 5 5 3 4 7 3 5 5 4 5 6 7 2 4 6 1 5 6 1 5 7 2 3 7 2 4 6 2 1 6 2 3 5 Debug Test 2 4 5 1 2 5 1 4 6 2 3 5 2 4 5 3 4 6 7 1 5 6 1 1 6 1 5 5 1 1 6 1 5 6 2 2 6 2 3 6 */

Compilation message (stderr)

bridges.cpp: In function 'int main()':
bridges.cpp:225:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  225 |         freopen(name".INP","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
bridges.cpp:226:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  226 |         freopen(name".OUT","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...