#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 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... |