제출 #1321061

#제출 시각아이디문제언어결과실행 시간메모리
1321061JuanJLCollapse (JOI18_collapse)C++20
0 / 100
50 ms6900 KiB
#include "collapse.h" #include <bits/stdc++.h> #define fst first #define snd second #define pb push_back #define forn(i,a,b) for(int i = a; i<b; i++) #define SZ(x) (int)x.size() #define ALL(x) x.begin(),x.end() #define mset(a,v) memset(a,v,sizeof(a)) #define FIN ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; typedef long long ll; struct UnionFind{ ll n; vector<ll> p; vector<ll> sz; UnionFind(ll n=0):n(n),p(n,0),sz(n,1){ forn(i,0,n) p[i]=i; } ll Find(ll x){ return (p[x]==x?x:Find(p[x])); } void Union(ll a,ll b){ ll pa = Find(a); ll pb = Find(b); if(pa==pb) return; if(sz[pa]<sz[pb]){ p[pa]=pb; }else{ p[pb]=pa; if(sz[pa]==sz[pb]) sz[pa]++; } } }; ll n; bool cmpa1( const pair<pair<ll,ll>,ll> &a, const pair<pair<ll,ll>,ll> &b){ if(a.fst.snd < b.fst.snd) return true; else if(a.fst.snd > b.fst.snd) return false; else if( a.fst.fst<b.fst.fst) return true; else if( a.fst.fst>b.fst.fst) return false; return a.snd<b.snd; } // en ari tienen que estar activos o que aparecen en ord vector<int> solve(vector<pair<ll,ll>> ari, vector<pair<pair<ll,ll>,pair<ll,ll>>> ord, vector<pair<pair<ll,ll>,ll>> qu){ bool fij[SZ(ari)]; forn(i,0,SZ(ari)) fij[i]=true; forn(i,0,SZ(ord)){ fij[ lower_bound(ALL(ari), ord[i].snd )-ari.begin() ]=false; } vector<pair<ll,ll>> lari; // ari sorted by left node lari.pb({-1000,0}); forn(i,0,SZ(ari)) if(fij[i]) lari.pb(ari[i]); vector<pair<ll,ll>> rari; // ari sorted by right node forn(i,0,SZ(ari)) if(fij[i]) rari.pb({ari[i].snd,ari[i].fst}); sort(ALL(rari)); rari.pb({1000000000,0}); ll cnt = 0; ll cmp1[SZ(rari)]; // desde 0 hasta i UnionFind uf1(n); vector<int> res(SZ(qu)); ll k = 0; sort(ALL(qu)); forn(i,0,SZ(rari)){ while(k<SZ(qu) && qu[k].fst.snd<rari[i].fst){ UnionFind tmp(n); ll rcnt = 0; vector<ll> ract(SZ(ari),false); forn(h,0,SZ(ord)) if(ord[h].snd.snd<=qu[k].fst.snd && ord[h].fst.fst<=qu[k].fst.fst){ /// cout<<ord[h].snd.fst<<" "<<ord[h].snd.snd<<'\n'; if(ract[lower_bound(ALL(ari), ord[h].snd )-ari.begin() ]) ract[lower_bound(ALL(ari), ord[h].snd )-ari.begin() ]=false; else ract[lower_bound(ALL(ari), ord[h].snd )-ari.begin() ]=true; } forn(h,0,SZ(ract)) if(ract[h]){ //cout<<ari[h].fst<<" "<<ari[h].snd<<" se puede usar\n"; if(tmp.Find(uf1.Find(ari[h].fst))!=tmp.Find(uf1.Find(ari[h].snd))){ tmp.Union(uf1.Find(ari[h].fst), uf1.Find(ari[h].snd)); rcnt++; } } ll rres = (i-1>=0?cmp1[i-1]:0) - rcnt + qu[k].fst.snd+1 - (i-1>=0?rari[i-1].fst+1:0); /// cout<<qu[k].fst.fst<<" "<<qu[k].fst.snd<<" left "<<(i-1>=0?cmp1[i-1]:0)<<" - "<< rcnt<<" + "<< qu[k].fst.snd+1 <<" - "<< (i-1>=0?rari[i-1].fst+1:0)<<'\n'; res[k]=rres; k++; } if(rari[i].fst==1000000000) break; if(uf1.Find(rari[i].fst)!=uf1.Find(rari[i].snd)){ cnt++; uf1.Union(rari[i].fst,rari[i].snd); } cmp1[i]= rari[i].fst+1 - cnt; } // cout<<"--------------------\n"; sort(ALL(qu),cmpa1); k=0; cnt = 0; ll cmp2[SZ(lari)]; // desde n hasta i UnionFind uf2(n); for(int i = SZ(lari)-1; i>=0; i--){ while(k<SZ(qu) && qu[k].fst.snd+1>lari[i].fst){ UnionFind tmp(n); ll rcnt = 0; vector<ll> ract(SZ(ari),0); forn(h,0,SZ(ord)) if(ord[h].snd.fst>=qu[k].fst.snd+1 && ord[h].fst.fst<=qu[k].fst.fst){ //cout<<ord[h].snd.fst<<" "<<ord[h].snd.snd<<'\n'; if(ract[ lower_bound(ALL(ari), ord[h].snd) - ari.begin() ]) ract[ lower_bound(ALL(ari) , ord[h].snd) - ari.begin()]=false; else ract[ lower_bound(ALL(ari), ord[h].snd)- ari.begin()] = true; } forn(h,0,SZ(ari)) if(ract[h]){ //cout<<" se puede usar "<<ari[h].fst<<" "<<ari[h].snd<<'\n'; if(tmp.Find(uf2.Find(ari[h].fst))!=tmp.Find(uf2.Find(ari[h].snd))){ tmp.Union(uf2.Find(ari[h].fst),uf2.Find(ari[h].snd)); rcnt++; } } ll rres = (i+1<SZ(lari)?cmp2[i+1]:0) -rcnt + (n-(qu[k].fst.snd+1)) - (i+1<SZ(lari)?n-(lari[i+1].fst+1):0); //cout<<qu[k].fst.fst<<" "<<qu[k].fst.snd<<" right "<<(i+1<SZ(lari)?cmp2[i+1]:0)<<" - "<<rcnt<<" + "<<(n-(qu[k].fst.snd+1))<<" - "<< (i+1<SZ(lari)?n-(lari[i+1].fst+1):0)<<'\n'; res[qu[k].snd]+=rres; k++; } if(lari[i].fst<0) break; if(uf2.Find(lari[i].fst)!=uf2.Find(lari[i].snd)){ cnt++; uf2.Union(lari[i].fst,lari[i].snd); } cmp2[i]=(n-lari[i].fst) - cnt; } return res; } std::vector<int> simulateCollapse( int N, std::vector<int> T, std::vector<int> X, std::vector<int> Y, std::vector<int> W, std::vector<int> P) { n=N; vector<pair<ll,ll>> ari; forn(i,0,SZ(X)) ari.pb({min(X[i],Y[i]),max(X[i],Y[i])}); sort(ALL(ari)); ari.erase(unique(ALL(ari)),ari.end()); vector<bool> act(SZ(ari),false); vector<pair<pair<ll,ll>,pair<ll,ll>>> ord; forn(i,0,SZ(T)) ord.pb({{i,T[i]},{min(X[i],Y[i]),max(X[i],Y[i])}}); vector<pair<pair<ll,ll>,ll>> qu; forn(i,0,SZ(W)) qu.pb({{W[i],P[i]},i}); sort(ALL(qu)); vector<int> res = solve(ari,ord,qu); return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...