제출 #1033198

#제출 시각아이디문제언어결과실행 시간메모리
1033198ASN49K다리 (APIO19_bridges)C++14
100 / 100
2507 ms13068 KiB
#define LOCAL 1 #include <bits/stdc++.h> using namespace std; using i64=long long; #define all(x) x.begin(),x.end() #define pb push_back #define UNSET -1 const int N = 50'000; const int SQRT=230; namespace dsu_roll_back { static int t[N],sz[N]; static int sk[N],sk_size; void roll_back() { while(sk_size>0) { sz[t[sk[sk_size-1]]]-=sz[sk[sk_size-1]]; t[sk[sk_size-1]]=sk[sk_size-1]; sk_size--; } } int root(int x) { if(t[x]!=x) { return root(t[x]); } return x; } void unite(int x,int y,bool roll) { x=root(x); y=root(y); if(sz[x]<sz[y]) { swap(x,y); } if(x==y) { return; } t[y]=x; sz[x]+=sz[y]; if(roll) { sk[sk_size++]=y; } } void init(int n) { fill(sz,sz+n,1); iota(t,t+n , 0); sk_size=0; } int size(int x) { return sz[root(x)]; } } //do not edge kids struct edge { int x,y,weight; bool operator ==(const edge& b)const { return x==b.x && y==b.y && weight==b.weight; } }; struct query { int tip,poz,weight,rez; }; static int n,m,q; static vector<edge>edges; static vector<query>querys; static set<pair<int,int>>mp; int old[N]; void solve_batch(const int l,const int r) { vector<bool>appears(m,false); for(int i=l;i<r;i++) { if(querys[i].tip==1) { appears[querys[i].poz]=true; } } vector<int>good; vector<int>bad; good.reserve(n); bad.reserve(r-l+1); for(auto &c:mp) { if(!appears[c.second]) { good.pb(c.second); } else { bad.pb(c.second); } } for(auto &c:bad) { mp.erase({-edges[c].weight , c}); } vector<int>ord_querys(r-l,0); iota(all(ord_querys) , l); sort(all(ord_querys) , [&](int x,int y){ if(querys[x].weight==querys[y].weight) { return querys[x].tip<querys[y].tip; } return querys[x].weight>querys[y].weight; }); vector<int>::iterator it_good=good.begin(); vector<int>::iterator it_ord_querys=ord_querys.begin(); dsu_roll_back::init(n); for(;it_ord_querys!=ord_querys.end();it_ord_querys++) { if(querys[*it_ord_querys].tip==1) { continue; } for(;it_good!=good.end() && edges[*it_good].weight>=querys[*it_ord_querys].weight;it_good++) { dsu_roll_back::unite(edges[*it_good].x , edges[*it_good].y ,false); } for(int i=l;i<*it_ord_querys;i++) { if(querys[i].tip==1) { old[i-l]=edges[querys[i].poz].weight; edges[querys[i].poz].weight=querys[i].weight; } } for(auto &c:bad) { if(edges[c].weight>=querys[*it_ord_querys].weight) { dsu_roll_back::unite(edges[c].x , edges[c].y , true); } } querys[*it_ord_querys].rez=dsu_roll_back::size(querys[*it_ord_querys].poz); for(int i=*it_ord_querys-1;i>=l;i--) { if(querys[i].tip==1) { edges[querys[i].poz].weight=old[i-l]; } } dsu_roll_back::roll_back(); } for(int i=l;i<r;i++) { if(querys[i].tip==1) { edges[querys[i].poz].weight=querys[i].weight; } } for(auto &c:bad) { mp.insert({-edges[c].weight , c}); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin>>n>>m; edges.resize(m); for(int i=0;i<m;i++) { int x,y,z; cin>>x>>y>>z; x--; y--; mp.insert({-z , i}); edges[i]={x,y,z}; } cin>>q; querys.resize(q); for(int i=0;i<q;i++) { cin>>querys[i].tip>>querys[i].poz>>querys[i].weight; querys[i].poz--; } for(int i=0;i<q;i+=SQRT) { solve_batch(i,min(i+SQRT,q)); } for(int i=0;i<q;i++) { if(querys[i].tip==2) { cout<<querys[i].rez<<'\n'; } } }
#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...