Submission #934432

#TimeUsernameProblemLanguageResultExecution timeMemory
934432VladaMG98Bridges (APIO19_bridges)C++17
43 / 100
365 ms14280 KiB
// Problem: B - Bridges // Contest: Virtual Judge - 2024-02-27 APIO Simulation // URL: https://vjudge.net/contest/612540#problem/B // Memory Limit: 512 MB // Time Limit: 3000 ms // // Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() #define print(A,t) cerr << #A << ": "; copy(all(A),ostream_iterator<t>(cerr," " )); cerr << endl #define prArr(A,n,t) cerr << #A << ": "; copy(A,A + n,ostream_iterator<t>(cerr," " )); cerr << endl #define what_is(x) cerr << #x << " is " << x << endl typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef vector<int> vi; const int MAXN = 100010; int from[MAXN], to[MAXN], weg[MAXN]; int type[MAXN], a[MAXN], b[MAXN]; vector<int> g[MAXN]; void dfs (int src, int bnd, vector<bool> &visited) { visited[src] = true; for (int e : g[src]) { int ot = from[e] + to[e] - src; if (!visited[ot] && bnd <= weg[e]) { dfs(ot, bnd, visited); } } } int n, m, q; void subtask1() { for (int qq = 1; qq <= q; qq++) { int t = type[qq]; if (t == 1) { weg[a[qq]] = b[qq]; } else { int src = a[qq], boundary = b[qq]; vector<bool> visited(n + 1, false); dfs(src, boundary, visited); int ans = 0; for (int i = 1; i <= n; i++) { if (visited[i]) ans += 1; } cout << ans << endl; } } } int t[MAXN << 1]; int seg_n; void build() { for (int i = seg_n - 1; i > 0; --i) t[i] = min(t[i << 1], t[i << 1 | 1]); } void modify (int pos, int val) { for (t[pos += seg_n] = val; pos > 1; pos >>= 1) t[pos >> 1] = min(t[pos], t[pos ^ 1]); } int query (int l, int r) { int ans = INT_MAX; for (l += seg_n, r += seg_n; l < r; l >>= 1, r >>= 1) { if (l & 1) ans = min(ans, t[l++]); if (r & 1) ans = min(ans, t[--r]); } return ans; } void subtask2() { seg_n = n - 1; for (int i = 1; i <= m; i++) { t[i - 1 + seg_n] = weg[i]; } build(); for (int qq = 1; qq <= q; qq++) { if (type[qq] == 1) { int pos = a[qq] - 1, val = b[qq]; modify(pos, val); } else { int pos = a[qq] - 1, with = b[qq]; int can_l = 0, can_r = 0; { int lo = 0, hi = pos; while (lo <= hi) { int mid = (lo + hi) / 2; if (query(pos - mid, pos) < with) { hi = mid - 1; } else { can_l = mid; lo = mid + 1; } } } { int lo = 0, hi = n - 1 - pos; while (lo <= hi) { int mid = (lo + hi) / 2; if (query(pos, pos + mid) < with) { hi = mid - 1; } else { can_r = mid; lo = mid + 1; } } } cout << can_l + 1 + can_r << endl; } } } struct event { int weg; int type; // weg -- weight of the edge // type -- if positive, an edge // if negative, a query event (int _weg, int _type) : weg(_weg), type(_type) {} bool operator < (const event &other) const { if (weg == other.weg) return type < other.type; return weg < other.weg; } }; struct dsu { vi par, sz; dsu (int _n) { par.resize(_n + 1); sz.resize(_n + 1); for (int i = 1; i <= _n; i++) { par[i] = i; sz[i] = 1; } } int get (int x) { if (par[x] == x) return x; return par[x] = get(par[x]); } bool unite (int u, int v) { u = get(u); v = get(v); if (u == v) return false; if (sz[u] > sz[v]) swap(u, v); par[u] = v; sz[v] += sz[u]; return true; } int get_size (int u) { return sz[get(u)]; } }; void subtask4() { vector<event> events; for (int i = 1; i <= m; i++) { events.emplace_back(weg[i], i); } for (int i = 1; i <= q; i++) { events.emplace_back(b[i], -i); } vector<int> answer(q + 1, 0); sort(all(events)); reverse(all(events)); dsu d(n + 1); for (auto e : events) { if (e.type > 0) d.unite(from[e.type], to[e.type]); else { answer[-e.type] = d.get_size(a[-e.type]); } } for (int i = 1; i <= q; i++) { cout << answer[i] << endl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> from[i] >> to[i] >> weg[i]; g[from[i]].push_back(i); g[to[i]].push_back(i); } cin >> q; for (int i = 1; i <= q; i++) { cin >> type[i] >> a[i] >> b[i]; } if (n <= 1000 && m <= 1000 && q <= 10000) { subtask1(); return 0; } bool is_two = false; if (m == n - 1) { is_two = true; for (int i = 1; i <= m; i++) { if (from[i] == i && to[i] == i + 1) continue; is_two = false; break; } } if (is_two) { subtask2(); return 0; } bool is_four = true; for (int i = 1; i <= q; i++) { if (type[i] != 2) { is_four = false; break; } } if (is_four) { subtask4(); return 0; } 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...