Submission #223385

#TimeUsernameProblemLanguageResultExecution timeMemory
223385jamielimMatching (COCI20_matching)C++14
18 / 110
30 ms25472 KiB
#include <bits/stdc++.h> using namespace std; int n; pair<int,int> arr[100005]; pair<int,int> adj[2][100005]; vector<int> al[100005]; struct node{ int s,e,m,v; node *l,*r; node(int S,int E){ s=S;e=E;m=(s+e)/2;v=0; if(s!=e){l=new node(s,m);r=new node(m+1,e);} } void upd(int x,int add){ if(s==e){v+=add;return;} if(x<=m)l->upd(x,add); else r->upd(x,add); v=l->v+r->v; } int qry(int x,int y){ if(s==x&&e==y)return v; if(y<=m)return l->qry(x,y); if(x>m)return r->qry(x,y); return l->qry(x,m)+r->qry(m+1,y); } }*root; //point modify range sum query bool poss(vector<pair<int,int> > v){ //check whether the connections here intersect (false) or not (true) vector<pair<int,int> > hor,ver[100005]; for(int i=0;i<(int)v.size();i++){ if(arr[v[i].first].first==arr[v[i].second].first){ ver[arr[v[i].first].first].push_back(make_pair(arr[v[i].first].second,arr[v[i].second].second)); }else{ int a=arr[v[i].first].first,b=arr[v[i].second].first; if(a>b)swap(a,b); hor.push_back(make_pair(a,arr[v[i].first].second));hor.push_back(make_pair(b,-arr[v[i].second].second)); } } sort(hor.begin(),hor.end()); root=new node(0,100005); int ptr=0; for(int i=0;i<100005;i++){ while(ptr<(int)hor.size()&&hor[ptr].first<=i){ if(hor[ptr].second>0)root->upd(hor[ptr].second,1); else root->upd(-hor[ptr].second,-1); ptr++; } for(int j=0;j<(int)ver[i].size();j++){ int a=ver[i][j].first,b=ver[i][j].second; if(a>b)swap(a,b); if(root->qry(a,b)>0){ return false; } } } return true; } int main(){ scanf("%d",&n); for(int i=0;i<100005;i++)adj[0][i]=adj[1][i]=make_pair(-1,-1); for(int i=0;i<n;i++){ scanf("%d%d",&arr[i].first,&arr[i].second); if(adj[0][arr[i].first].first==-1)adj[0][arr[i].first].first=i; else adj[0][arr[i].first].second=i; if(adj[1][arr[i].second].first==-1)adj[1][arr[i].second].first=i; else adj[1][arr[i].second].second=i; } for(int i=0;i<n;i++){ if(adj[0][arr[i].first].second==-1&&adj[1][arr[i].second].second==-1){ //no friends printf("NE");return 0; } if(adj[0][arr[i].first].second!=-1){ //vertical friend if(adj[0][arr[i].first].first==i)al[i].push_back(adj[0][arr[i].first].second); else al[i].push_back(adj[0][arr[i].first].first); } if(adj[1][arr[i].second].second!=-1){ //horizontal friend if(adj[1][arr[i].second].first==i)al[i].push_back(adj[1][arr[i].second].second); else al[i].push_back(adj[1][arr[i].second].first); } //draw directed edges, the other direction will be drawn by the other person } //for(int i=0;i<n;i++){for(int j=0;j<(int)al[i].size();j++)printf("%d ",al[i][j]);printf("\n");} vector<pair<int,int> > ans; //consider "forced" friends (degree 1) queue<int> q; for(int i=0;i<n;i++){ if((int)al[i].size()==1)q.push(i); } while(!q.empty()){ int cur=q.front();q.pop(); for(int i=0;i<(int)al[cur].size();i++){ //1 or 0 int x=al[cur][i]; if((int)al[x].size()==2){ if(al[x][0]==cur){ al[x][0]=al[x][1]; } al[x].pop_back(); //get rid of cur from x friend list ans.push_back(make_pair(cur,x)); //now x not allowed to have friends anymore int y=al[x][0]; if((int)al[y].size()==1){ printf("NE"); return 0; //y has no friends because x is friends with cur }else{ assert((int)al[y].size()==2); if(al[y][0]==x)al[y][0]=al[y][1]; al[y].pop_back(); q.push(y); //push cur's friend's friend into the queue } }else if((int)al[x].size()==1){ ans.push_back(make_pair(cur,x)); } al[x].clear(); } al[cur].clear(); } //for(int i=0;i<n;i++){for(int j=0;j<(int)al[i].size();j++)printf("%d ",al[i][j]);printf("\n");} //everything left in al is degree 2, connect these in one direction vector<pair<int,int> > ans2;for(int i=0;i<(int)ans.size();i++)ans2.push_back(ans[i]); //ans is vertical, ans2 is horizontal. need to check whether things intersect at the end for(int i=0;i<n;i++){ if((int)al[i].size()==0)continue; assert((int)al[i].size()==2); if(arr[al[i][0]].first==arr[i].first&&al[i][0]<i){ ans.push_back(make_pair(al[i][0],i)); }else if(arr[al[i][1]].first==arr[i].first&&al[i][1]<i){ ans.push_back(make_pair(al[i][1],i)); } if(arr[al[i][0]].second==arr[i].second&&al[i][0]<i){ ans2.push_back(make_pair(al[i][0],i)); }else if(arr[al[i][1]].second==arr[i].second&&al[i][1]<i){ ans2.push_back(make_pair(al[i][1],i)); } } if(poss(ans)){ if(n>40)return 1; printf("DA\n"); for(int i=0;i<(int)ans.size();i++){ printf("%d %d\n",ans[i].first+1,ans[i].second+1); } }else if(poss(ans2)){ if(n>40)return 2; printf("DA\n"); for(int i=0;i<(int)ans2.size();i++){ printf("%d %d\n",ans2[i].first+1,ans2[i].second+1); } }else{ printf("NE"); } }

Compilation message (stderr)

matching.cpp: In function 'int main()':
matching.cpp:63:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d",&n);
  ~~~~~^~~~~~~~~
matching.cpp:66:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d",&arr[i].first,&arr[i].second);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...