This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5, magic = 800;
struct State
{
int Time;
int *fi; int se;
State(int _Time, int* _fi, int _se):
Time(_Time), fi(_fi), se(_se) {};
};
struct pdsu
{
vector<int> par, sz;
vector<State> saved;
void init(int n)
{
par.assign(n + 5, 0); sz.assign(n + 5, 1);
for (int i = 0; i < n + 5; ++i){
par[i] = i;
}
saved.clear();
}
int finds(int u, int Time)
{
if (par[u] != u){
saved.pb({Time, &par[u], par[u]});
par[u] = finds(par[u], Time);
}
return par[u];
}
bool same(int u, int v, int Time)
{
return finds(u, Time) == finds(v, Time);
}
bool merges(int u, int v, int Time)
{
u = finds(u, Time); v = finds(v, Time);
if (u == v) return false;
if (sz[u] < sz[v]) swap(u, v);
saved.pb({Time, &par[v], par[v]});
saved.pb({Time, &sz[u], sz[u]});
saved.pb({Time, &sz[v], sz[v]});
sz[u] += sz[v]; sz[v] = 0;
par[v] = u;
return true;
}
void rollback(int Time)
{
while (saved.size() && saved.back().Time == Time){
*saved.back().fi = saved.back().se;
saved.pop_back();
}
}
}dsu;
struct edge_list
{
int u, v, w, id;
edge_list(int u = 0, int v = 0, int w = 0, int id = 0):
u(u), v(v), w(w), id(id) {}
bool operator < (const edge_list & other) const
{
return w < other.w;
}
};
struct Query
{
int pos, id, val;
bool operator < (const Query & other) const
{
return val < other.val;
}
};
edge_list edge[maxn];
int N, M, Q;
int type[maxn], pos[maxn], val[maxn];
int ret[maxn], id[maxn], change[maxn];
bool in_quer[maxn];
signed main(void)
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
if (fopen("A.INP", "r")){
freopen("A.INP", "r", stdin);
freopen("A.OUT", "w", stdout);
}
cin >> N >> M;
for (int i = 1; i <= M; ++i){
cin >> edge[i].u >> edge[i].v >> edge[i].w;
edge[i].w = -edge[i].w;
edge[i].id = i;
}
sort(edge + 1, edge + 1 + M);
cin >> Q;
for (int i = 1; i <= Q; ++i){
cin >> type[i] >> pos[i] >> val[i];
val[i] = -val[i];
}
for (int i = 1; i <= Q; i += magic){
vector<int> in_tree;
for (int j = 1; j <= M; ++j){
id[edge[j].id] = j;
}
dsu.init(N);
for (int j = i; j <= Q && j < i + magic; ++j){
if (type[j] == 1){
in_quer[id[pos[j]]] = true;
}
}
for (int j = 1; j <= M; ++j){
if (in_quer[j] == false){
if (dsu.merges(edge[j].u, edge[j].v, 0)){
in_tree.pb(j);
}
}
}
dsu.init(N);
vector<Query> qr;
vector<int> logs;
for (int j = i; j <= Q && j < i + magic; ++j){
if (type[j] == 1){
if (in_quer[id[pos[j]]]){
logs.pb(pos[j]);
in_quer[id[pos[j]]] = false;
}
}
else{
qr.pb({pos[j], j, val[j]});
}
}
sort(qr.begin(), qr.end());
int pt = 0;
for (auto & all : qr){
while (pt < (int)in_tree.size() && edge[in_tree[pt]].w <= all.val){
dsu.merges(edge[in_tree[pt]].u, edge[in_tree[pt]].v, 0);
++pt;
}
for (int j = i; j < all.id; ++j){
if (type[j] == 1){
change[pos[j]] = val[j];
}
}
for (auto & it : logs){
int cost;
if (change[it] == 0) cost = edge[id[it]].w;
else cost = change[it];
if (cost <= all.val) dsu.merges(edge[id[it]].u, edge[id[it]].v, 1);
}
ret[all.id] = dsu.sz[dsu.finds(all.pos, 1)];
dsu.rollback(1);
for (int j = i; j < all.id; ++j){
if (type[j] == 1){
change[pos[j]] = 0;
}
}
}
for (int j = i; j <= Q && j < i + magic; ++j){
change[pos[j]] = val[j];
}
vector<edge_list> l, r;
for (int j = 1; j <= M; ++j){
if (change[edge[j].id]){
edge[j].w = change[edge[j].id];
change[edge[j].id] = 0;
r.pb(edge[j]);
}
else l.pb(edge[j]);
}
sort(r.begin(), r.end());
merge(l.begin(), l.end(), r.begin(), r.end(), edge + 1);
}
for (int i = 1; i <= Q; ++i){
if (type[i] == 2) cout << ret[i] << '\n';
}
}
Compilation message (stderr)
bridges.cpp: In function 'int main()':
bridges.cpp:96:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
freopen("A.INP", "r", stdin);
~~~~~~~^~~~~~~~~~~~~~~~~~~~~
bridges.cpp:97:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
freopen("A.OUT", "w", stdout);
~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
# | 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... |