이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
#define all(x) begin(x), end(x)
using namespace std;
using ll = long long;
const int maxn = 101100, B = 12;
int n, m, q, old[maxn], touch[maxn], ans[maxn];
vector<array<int, 4>> edges;
vector<array<int, 2>> weights[maxn];
struct dsu {
vector<int> r, p, rb;
dsu(int n = 0) : r(n, 1), p(n) { iota(all(p), 0); }
int par(int v) {
if(p[v] == v) return v;
return par(p[v]);
}
void unite(int i, int j) {
i = par(i), j = par(j);
rb.push_back(-1);
if(i == j) return;
if(r[i] < r[j]) swap(i, j);
p[j] = i;
r[i] += r[j];
rb.push_back(j);
}
void roll_back(int c) {
while(c--) {
int v = rb.back(); rb.pop_back();
if(v == -1) continue;
r[p[v]] -= r[v];
p[v] = v;
}
}
};
int get_weight(int e, int t) {
e = edges[e][3];
int i = weights[e].size()-1;
while(weights[e][i][0] > t) {
i--;
}
return weights[e][i][1];
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n >> m;
edges.resize(m);
int tmp = 1;
for(auto &[x, y, z, old_id] : edges) {
cin >> x >> y >> z, x--, y--, old_id = tmp++;
z *= -1;
}
sort(all(edges), [](auto &a, auto &b) { return a[2] < b[2]; });
tmp = 0;
for(auto &[x, y, z, old_id] : edges) {
weights[old_id].push_back({-1, z});
old[old_id] = tmp++;
}
memset(ans, -1, sizeof ans);
cin >> q;
//cout << q << endl;
for(int l = 0; l < q; l+=B) {
int r = min(q, l+B);
vector<array<int, 3>> todo;
vector<int> touched;
sort(all(edges), [&](auto &I, auto &J) { int i = weights[I[3]].back()[1], j = weights[J[3]].back()[1]; return i < j || (i == j && I[3] < J[3]); });
for(int t, a, b, i = l; i < r; i++) {
cin >> t >> a >> b;
//cout << t << " " << a << " " << b << endl;
b *= -1;
//cout << i << " T IS EQUAL TO " << t << " FFS " << a << " " << b<< endl;
if(t == 1) {
//cout << "BIG A " << a << endl;
if(touch[a] != 1+l) touched.push_back(old[a]);
touch[a] = 1+l;
weights[a].push_back({i, b});
} else {
a--;
todo.push_back({b, a, i});
}
}
sort(all(todo));
sort(all(touched), [&](auto &i, auto &j) { return get_weight(i, q) < get_weight(j, q) || (get_weight(i, q) == get_weight(j, q) && i < j); });
touched.erase(unique(all(touched)), touched.end());
dsu d(n);
// cout << l << endl;
{int lst = -(1<<30), tmp = 0;
for(auto &[u, w, U, i] : edges) {if(touch[i] != 1+l) {
//cout << i << " ! " << touch[i] << endl;
//cout << lst << " " << get_weight(tmp, q) << endl;
assert(lst <= get_weight(tmp, q));
lst = get_weight(tmp, q);
}tmp++;}
}
for(int j = 0, I = 0; I < todo.size(); I++) {
int t = todo[I][2], w = todo[I][0], v = todo[I][1];
j = 0;d = dsu(n);
while(j < m) {
if(touch[edges[j][3]] == 1+l) {j++; continue;}
if(get_weight(j, q) > w) break;
d.unite(edges[j][0], edges[j][1]);
j++;
}
int rb = 0;
for(auto i : touched) if(get_weight(i, t) <= w) rb++, d.unite(edges[i][0], edges[i][1]);
ans[t] = d.r[d.par(v)];
d.roll_back(rb);
}
vector<array<int, 4>> edges_new;
vector<int> te;
tmp = 0;
for(auto &i : edges) {if(touch[edges[tmp][3]] != 1+l) te.push_back(tmp); tmp++;}
{map<int, int> cnt;for(auto &i : te) if(cnt[i]++ > 1) exit(32); }
{map<int, int> cnt;for(auto &i : touched) if(cnt[i]++ > 1) exit(32); }
int i = 0, j = 0;
while(i < te.size() || j < touched.size()) {
if(i < te.size() && (j == touched.size() || get_weight(te[i], q) < get_weight(touched[j], q))) {
edges_new.push_back(edges[te[i++]]);
} else edges_new.push_back(edges[touched[j++]]);
}
edges = edges_new;
sort(all(edges_new), [&](auto &I, auto &J) { int i = weights[I[3]].back()[1], j = weights[J[3]].back()[1]; return i < j || (i == j && I[3] < J[3]); });
tmp = 0;
int lst = -(1<<30);
for(auto &[x, y, z, old_id] : edges) {
old[old_id] = tmp++;
assert(lst <= weights[old_id].back()[1]);
}
if(edges.size() < m) exit(47);
}
for(int i = 0; i < q; i++) if(ans[i] >= 0) cout << ans[i] << '\n';
}
컴파일 시 표준 에러 (stderr) 메시지
bridges.cpp: In function 'int main()':
bridges.cpp:96:33: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::array<int, 3> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
96 | for(int j = 0, I = 0; I < todo.size(); I++) {
| ~~^~~~~~~~~~~~~
bridges.cpp:113:19: warning: unused variable 'i' [-Wunused-variable]
113 | for(auto &i : edges) {if(touch[edges[tmp][3]] != 1+l) te.push_back(tmp); tmp++;}
| ^
bridges.cpp:120:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
120 | while(i < te.size() || j < touched.size()) {
| ~~^~~~~~~~~~~
bridges.cpp:120:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
120 | while(i < te.size() || j < touched.size()) {
| ~~^~~~~~~~~~~~~~~~
bridges.cpp:121:12: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
121 | if(i < te.size() && (j == touched.size() || get_weight(te[i], q) < get_weight(touched[j], q))) {
| ~~^~~~~~~~~~~
bridges.cpp:121:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
121 | if(i < te.size() && (j == touched.size() || get_weight(te[i], q) < get_weight(touched[j], q))) {
| ~~^~~~~~~~~~~~~~~~~
bridges.cpp:134:19: warning: comparison of integer expressions of different signedness: 'std::vector<std::array<int, 4> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
134 | if(edges.size() < m) exit(47);
| ~~~~~~~~~~~~~^~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |