제출 #719568

#제출 시각아이디문제언어결과실행 시간메모리
719568keisuke6다리 (APIO19_bridges)C++14
16 / 100
1010 ms71748 KiB
#include <bits/stdc++.h> using namespace std; #define int long long bool f(vector<int> S){ for(int x:S)if(x==1) return false; return true; } struct Unionfind{ vector<int> par, siz; //初期化 Unionfind(int n) : par(n,-1) , siz(n,1) {} int root(int x) { if(par[x] == -1) return x; else return par[x] = root(par[x]); } bool issame(int x,int y) { return root(x) == root(y); } bool unite(int x, int y){ x = root(x); y = root(y); if(x == y) return false; if(siz[x] < siz[y]) swap(x,y); par[y] = x; siz[x] += siz[y]; return true; } int size(int x) { return siz[root(x)]; } }; template <typename T> struct RMQ { const T INF = numeric_limits<T>::max(); int n; // 葉の数 vector<T> dat; // 完全二分木の配列 RMQ(int n_) : n(), dat(n_ * 4, INF) { // 葉の数は 2^x の形 int x = 1; while (n_ > x) { x *= 2; } n = x; } void update(int i, T x) { i += n - 1; dat[i] = x; while (i > 0) { i = (i - 1) / 2; // parent dat[i] = min(dat[i * 2 + 1], dat[i * 2 + 2]); } } // the minimum element of [a,b) T query(int a, int b) { return query_sub(a, b, 0, 0, n); } T query_sub(int a, int b, int k, int l, int r) { if (r <= a || b <= l) { return INF; } else if (a <= l && r <= b) { return dat[k]; } else { T vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2); T vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r); return min(vl, vr); } } }; signed main(){ int N,M,Q; cin>>N>>M; RMQ<int> seg(N-1); vector<vector<int>> G(N); unordered_map<int,int> m; map<int,multiset<int>> s; map<int,pair<int,int>> ed; map<int,int> edc; for(int i=0;i<M;i++){ int a,b,c; cin>>a>>b>>c; a--; b--; seg.update(i,c); ed[i] = {a,b}; edc[i] = c; m[a*N+b] = max(c,m[a*N+b]); m[b*N+a] = max(c,m[a*N+b]); s[a*N+b].insert(c); s[b*N+a].insert(c); G[a].push_back(b); G[b].push_back(a); } cin>>Q; vector<int> T(Q),A(Q),B(Q); for(int i=0;i<Q;i++){ cin>>T[i]>>A[i]>>B[i]; A[i]--; } if(f(T)){ Unionfind uf(N); vector<pair<int,int>> S(Q); for(int i=0;i<Q;i++) S[i] = {B[i],A[i]}; map<int,int> ans; sort(S.rbegin(),S.rend()); vector<tuple<int,int,int>> C = {}; for(int i=0;i<N;i++)for(int j:G[i]){ C.push_back({m[i*N+j],i,j}); } sort(C.rbegin(),C.rend()); int ind = 0; for(int i=0;i<Q;i++){ while(ind != 2*(int)(m.size())){ int a,b,c; tie(a,b,c) = C[ind]; if(a < S[i].first) break; uf.unite(b,c); ind++; } ans[S[i].first*N+S[i].second] = uf.size(S[i].second); } for(int i=0;i<Q;i++) cout<<ans[B[i]*N+A[i]]<<endl; return 0; } if(max({N,M,Q}) <= 10000){ for(int i=0;i<Q;i++){ if(T[i] == 1){ int a,b; tie(a,b) = ed[A[i]]; s[a*N+b].erase(s[a*N+b].find(edc[A[i]])); s[a*N+b].insert(B[i]); swap(a,b); s[a*N+b].erase(s[a*N+b].find(edc[A[i]])); s[a*N+b].insert(B[i]); edc[A[i]] = B[i]; continue; } queue<int> q; q.push(A[i]); vector<bool> seen(N,false); seen[A[i]] = true; while(!q.empty()){ int pos = q.front(); q.pop(); for(int x:G[pos]){ if(seen[x] || *s[pos*N+x].rbegin() < B[i]) continue; seen[x] = true; q.push(x); } } int count = 0; for(int i=0;i<N;i++) count += seen[i]; cout<<count<<endl; } return 0; } for(int i=0;i<Q;i++){ if(T[i] == 1){ seg.update(A[i],B[i]); continue; } int ans = 1; if(A[i]){ int l = 0, r = A[i]-1; while(r-l > 1){ int mid = (l+r)/2; if(seg.query(mid,A[i]) >= B[i]) r = mid; else l = mid; } if(seg.query(A[i]-1,A[i]) < B[i]) ans += 0; else if(seg.query(0,A[i]) >= B[i]) ans += A[i]; else ans += A[i]-r; } if(A[i] != N-1){ int l = A[i]+1, r = N; while(r-l > 1){ int mid = (l+r)/2; if(seg.query(A[i],mid) >= B[i]) l = mid; else r = mid; } if(seg.query(A[i],A[i]+1) < B[i]) ans += 0; else if(seg.query(A[i],N-1) >= B[i]) ans += N-1-A[i]; else ans += l-A[i]; } cout<<ans<<endl; } }
#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...