제출 #463913

#제출 시각아이디문제언어결과실행 시간메모리
463913czhang2718다리 (APIO19_bridges)C++14
100 / 100
2943 ms6756 KiB
#pragma GCC target ("avx2") #include<bits/stdc++.h> using namespace std; #define rep(i, a, b) for(int i=a; i<=b; i++) #define all(x) x.begin(), x.end() #define sz(x) (int) x.size() #define f first #define s second #define pb push_back #define nl '\n' typedef vector<int> vi; typedef pair<int, int> pii; const int B=1000; int n, m, q; pair<int, pii> edge[100001]; bool t[100001]; pii query[100001]; bool skip[100001]; int par[100001]; int s[100001]; int ans[100001]; stack<int> changes; int use[100001]; int qedge[100001]; int edges[100001]; int qu[100001]; int find(int x){ while(x!=par[x]) x=par[x]; return x; } void join(int i, bool ch){ int a=find(edge[i].s.f); int b=find(edge[i].s.s); if(a==b) return; if(s[a]<s[b]) swap(a, b); if(ch) changes.push(b); par[b]=a; s[a]+=s[b]; } bool byw(int i, int j){ return query[i].s>query[j].s; } void undo(){ while(!changes.empty()){ int x=changes.top(); changes.pop(); s[par[x]]-=s[x]; par[x]=x; } } bool cmp(int i, int j){ return edge[i].f>edge[j].f; } int main(){ cin.tie(0)->sync_with_stdio(0); // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); cin >> n >> m; rep(i, 1, m){ int u, v, w; cin >> u >> v >> w; edge[i]={w, {u, v}}; } cin >> q; rep(i, 1, q){ int type; cin >> type >> query[i].f >> query[i].s; t[i]=type==1; } rep(b, 0, q/B){ rep(i, 1, n) par[i]=i, s[i]=1; int l=max(1, B*b); int r=min(q, B*(b+1)-1); iota(par+1, par+1+n, 1); fill(s+1, s+1+n, 1); rep(i, 1, m) skip[i]=0, use[i]=0; int qedgei=0; int qui=0; int edgesi=0; for(int i=l; i<=r; i++) { if(t[i]==1) skip[query[i].f]=1, qedge[qedgei++]=i; else qu[qui++]=i; } rep(i, 1, m) if(!skip[i]) edges[edgesi++]=i; sort(qu, qu+qui, byw); int k=0; sort(edges, edges+edgesi, cmp); for(int ind=0; ind<qui; ind++) { int i=qu[ind]; while(k<edgesi && edge[edges[k]].f>=query[i].s){ join(edges[k], 0); k++; } int p=0; while(p<qedgei && qedge[p]<=i) p++; for(int l=p-1; l>=0; l--) { int j=qedge[l]; if(query[j].s>=query[i].s && use[query[j].f]!=i) join(query[j].f, 1); use[query[j].f]=i; } for(int j=p; j<qedgei; j++) { int e=query[qedge[j]].f; if(use[e]!=i && edge[e].f>=query[i].s) join(e, 1), use[e]=i; } ans[i]=s[find(query[i].f)]; undo(); } rep(i, l, r){ if(t[i]==1) edge[query[i].f].f=query[i].s; } } rep(i, 1, q) if(!t[i]) cout << ans[i] << nl; } // q/B * (2mlogm+B) + q*B*log(m) // m * sqrt(q) * logm // 1e5 * 3e2 * 2e1 // 6e8
#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...