This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pi;
typedef tuple<int, int, int, int, int> edge; // weight, startTime, endTime, endpts (x2)
typedef tuple<int, int, int> query; // weight, time, pt
typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
#define pb push_back
#define f first
#define s second
namespace debug {
const int DEBUG = true;
template<class T1, class T2>
void pr(const pair<T1, T2> &x);
template<class T, size_t SZ>
void pr(const array<T, SZ> &x);
template<class T>
void pr(const vector<T> &x);
template<class T>
void pr(const set<T> &x);
template<class T1, class T2>
void pr(const map<T1, T2> &x);
template<class T>
void pr(const T &x) { if (DEBUG) cout << x; }
template<class T, class... Ts>
void pr(const T &first, const Ts &... rest) { pr(first), pr(rest...); }
template<class T1, class T2>
void pr(const pair<T1, T2> &x) { pr("{", x.f, ", ", x.s, "}"); }
template<class T>
void prIn(const T &x) {
pr("{");
bool fst = 1;
for (auto &a : x) {
pr(fst ? "" : ", ", a), fst = 0;
}
pr("}");
}
template<class T, size_t SZ>
void pr(const array<T, SZ> &x) { prIn(x); }
template<class T>
void pr(const vector<T> &x) { prIn(x); }
template<class T>
void pr(const set<T> &x) { prIn(x); }
template<class T1, class T2>
void pr(const map<T1, T2> &x) { prIn(x); }
void ps() { pr("\n"); }
template<class Arg, class... Args>
void ps(const Arg &first, const Args &... rest) {
pr(first, " ");
ps(rest...);
}
}
using namespace debug;
const int BLKSZ = 400;
const int NUMBLKS = 100000 / BLKSZ + 5;
const int MAXN = 50100;
struct DSU {
int anc[MAXN], sz[MAXN];
void init() {
for (int i = 0; i < MAXN; i++) {
anc[i] = i;
sz[i] = 1;
}
}
int fRt(int i) {
return anc[i] == i ? i : anc[i] = fRt(anc[i]);
}
bool merge(int a, int b) { // TODO: implement rank
a = fRt(a), b = fRt(b);
if (a == b) {
return false;
}
anc[a] = b;
sz[b] += sz[a];
return true;
}
} ds;
vector<vi> aList;
vector<bool> vis;
vector<int> undo;
int cnt = 0;
void dfs(int cV) {
vis[cV] = true;
cnt += ds.sz[cV];
for (int aV : aList[cV]) {
if (!vis[aV]) {
dfs(aV);
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int V, E, Q;
cin >> V >> E;
vector<edge> edges;
vector<pi> endP(E);
vi sT(E);
vi lW(E);
for (int i = 0; i < E; i++) {
int u, v, w;
cin >> u >> v >> w;
u--, v--;
endP[i] = {u, v};
sT[i] = -1;
lW[i] = w;
}
cin >> Q;
vector<vector<query>> qBlks(NUMBLKS);
vector<vector<edge>> eBlks(NUMBLKS);
for (int cT = 0; cT < Q; cT++) {
int t, x, w;
cin >> t >> x >> w;
x--;
if (t == 1) {
edge cE = {lW[x], sT[x], cT - 1, endP[x].f, endP[x].s};
edges.pb(cE);
eBlks[sT[x] / BLKSZ].pb(cE);
eBlks[(cT - 1) / BLKSZ].pb(cE);
sT[x] = cT;
lW[x] = w;
} else {
qBlks[cT / BLKSZ].pb({w, cT, x});
}
}
for (int x = 0; x < E; x++) {
edge cE = {lW[x], sT[x], 100005, endP[x].f, endP[x].s};
edges.pb(cE);
eBlks[sT[x] / BLKSZ].pb(cE);
}
edges.pb({-1, -1, -1, -1, -1}); // dummy edge to make sure all queries are processed
sort(edges.begin(), edges.end());
reverse(edges.begin(), edges.end());
// decreasing weight
vis.resize(V, false);
aList.resize(V);
vi qAns(Q, -1);
for (int cBlk = 0; cBlk < NUMBLKS; cBlk++) {
vector<query> &cQs = qBlks[cBlk];
vector<edge> &cEs = eBlks[cBlk];
sort(cQs.begin(), cQs.end());
reverse(cQs.begin(), cQs.end());
// decreasing weight
// ps("queries:");
// for(auto x : cQs){
// ps(get<0>(x), get<1>(x), get<2>(x));
// }
int blkL = cBlk * BLKSZ;
int blkR = (cBlk + 1) * BLKSZ - 1;
ds.init();
int nxtQ = 0;
for (edge oE: edges) {
int oW = get<0>(oE);
int oST = get<1>(oE);
int oET = get<2>(oE);
int oU = get<3>(oE);
int oV = get<4>(oE);
while (nxtQ < cQs.size() && get<0>(cQs[nxtQ]) > oW) {
int qW = get<0>(cQs[nxtQ]);
int qT = get<1>(cQs[nxtQ]);
int qPt = get<2>(cQs[nxtQ]);
// ps("qT:", qT);
// we have components determined by ds and a set of extra edges
for (edge iE : cEs) {
int iW = get<0>(iE);
int iST = get<1>(iE);
int iET = get<2>(iE);
int iU = ds.fRt(get<3>(iE));
int iV = ds.fRt(get<4>(iE));
if (iU == iV) { // useless
continue;
}
if (iST <= qT && qT <= iET && iW >= qW) { // usable iff within time zone and qW
aList[iU].pb(iV);
aList[iV].pb(iU);
undo.pb(iU);
undo.pb(iV);
// ps("added edge:", iV, iU);
}
}
dfs(ds.fRt(qPt));
qAns[qT] = cnt;
for (int cV : undo) {
aList[cV].clear();
vis[cV] = false;
}
undo.clear();
cnt = 0;
nxtQ++;
}
// only consider edges that completely surround this block
if (oST < blkL && blkR < oET) {
// merge endpoints in disjoint set
ds.merge(oU, oV);
}
}
}
for (int i = 0; i < Q; i++) {
if (qAns[i] != -1) {
cout << qAns[i] << '\n';
}
}
cout << flush;
}
Compilation message (stderr)
bridges.cpp: In function 'int main()':
bridges.cpp:211:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while (nxtQ < cQs.size() && get<0>(cQs[nxtQ]) > oW) {
~~~~~^~~~~~~~~~~~
# | 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... |