Submission #201749

#TimeUsernameProblemLanguageResultExecution timeMemory
201749alishahali1382Matching (COCI20_matching)C++14
5 / 110
22 ms15356 KiB
#include <bits/stdc++.h> #pragma GCC optimize ("O2") #pragma GCC optimize ("unroll-loops") //#pragma GCC optimize("no-stack-protector,fast-math") using namespace std; typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<pii, int> piii; typedef pair<ll, ll> pll; #define debug(x) cerr<<#x<<'='<<(x)<<endl; #define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl; #define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl; #define debugv(v) {cerr<<#v<<" : ";for (auto x:v) cerr<<x<<' ';cerr<<endl;} #define all(x) x.begin(), x.end() #define pb push_back #define kill(x) return cout<<x<<'\n', 0; const ld eps=1e-7; const int inf=1000000010; const ll INF=10000000000000010LL; const int mod = 1000000007; const int MAXN = 100010, SQ=320, CNT=MAXN/SQ+1; inline void erase(vector<int> &vec, int x){ if (vec.back()!=x) swap(vec[0], vec[1]); vec.pop_back(); } int n, m, k, u, v, x, y, t, a, b; int X[MAXN], Y[MAXN]; bool mark[MAXN]; vector<int> G[MAXN], vx[MAXN], vy[MAXN]; vector<pii> ans; queue<int> Q; inline bool bad(int a, int b, int c, int d){ bool t1=(X[a]==X[b]), t2=(X[c]==X[d]); if (t1==t2) return 0; if (t1){ swap(a, c); swap(b, d); } if (X[c]<X[a] || X[b]<X[c]) return 0; if (Y[c]>Y[d]) swap(c, d); return (Y[c]<=Y[a] && Y[a]<=Y[d]); } inline void disjoint(int u, int v){ erase(G[u], v); erase(G[v], u); } struct SQRT{ vector<int> vec[MAXN]; int L[MAXN], R[MAXN]; pii block[CNT][SQ]; // {L, pos} pii mx[CNT][SQ]; // {R, pos} void rebuild(int id){ for (int i=0; i<SQ; i++) block[id][i]={L[SQ*id+i], SQ*id+i}; sort(block[id], block[id]+SQ); for (int i=0; i<SQ; i++) mx[id][i]={R[block[id][i].second], block[id][i].second}; for (int i=1; i<SQ; i++) mx[id][i]=max(mx[id][i], mx[id][i-1]); } void Draw(int l, int r, int h){ if (l>r) swap(l, r); int idl=l/SQ, idr=r/SQ; while (l<r){ //debug(l) //debug2(L[l], R[l]) if (l%SQ==0 && l+SQ<=r){ int id=l/SQ; while (1){ int tmp=lower_bound(block[id], block[id]+SQ, pii(h, 0))-block[id]-1; if (tmp==-1 || mx[id][tmp].first<h) break ; int pos=mx[id][tmp].second; disjoint(vec[pos][0], vec[pos][1]); L[pos]=R[pos]=0; rebuild(id); } l+=SQ; } else{ if (L[l]<h && h<R[l]) disjoint(vec[l][0], vec[l][1]); l++; } } rebuild(idl); rebuild(idr); } } SQX, SQY; int main(){ ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); cin>>n; for (int i=1; i<=n; i++){ cin>>X[i]>>Y[i]; if (vx[X[i]].size()){ int j=vx[X[i]][0]; if (Y[i]==Y[j]){ mark[i]=mark[j]=1; ans.pb({j, i}); continue ; } G[i].pb(j); G[j].pb(i); } if (vy[Y[i]].size()){ int j=vy[Y[i]][0]; G[i].pb(j); G[j].pb(i); } vx[X[i]].pb(i); vy[Y[i]].pb(i); } for (int i=0; i<MAXN; i++){ if (vx[i].size()==2 && Y[vx[i][0]]>Y[vx[i][1]]) swap(vx[i][0], vx[i][1]); if (vy[i].size()==2 && X[vy[i][0]]>X[vy[i][1]]) swap(vy[i][0], vy[i][1]); SQX.vec[i]=vx[i]; SQY.vec[i]=vy[i]; } //debugv(vx[2]) for (int i=0; i<MAXN; i++) if (vx[i].size()==2) SQX.L[i]=Y[vx[i][0]], SQX.R[i]=Y[vx[i][1]]; for (int i=0; i<MAXN; i++) if (vy[i].size()==2) SQY.L[i]=X[vy[i][0]], SQY.R[i]=X[vy[i][1]]; for (int i=0; i<CNT; i++) SQX.rebuild(i), SQY.rebuild(i); /* SQX.Draw(1, 3, 2); debugv(G[3]) return 0; */ for (int i=1; i<=n; i++) if (G[i].size()<2) Q.push(i); while (Q.size()){ int v=Q.front(); Q.pop(); if (mark[v]) continue ; if (G[v].size()==0) kill("NE") int u=G[v][0]; mark[v]=mark[u]=1; ans.pb({u, v}); //debug2(u, v) for (int i:G[u]) if (i!=v){ erase(G[i], u); Q.push(i); } if (Y[u]==Y[v]) SQX.Draw(X[u], X[v], Y[u]); else SQY.Draw(Y[u], Y[v], X[u]); } for (int i=1; i<=n; i++) if (!mark[i]){ int j=G[i][0]; if (X[i]!=X[j]) j=G[i][1]; ans.pb({i, j}); mark[i]=mark[j]=1; } cout<<"DA\n"; for (pii p:ans) cout<<p.first<<' '<<p.second<<'\n'; return 0; } /* 4 10 20 30 20 20 30 20 10 */
#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...