제출 #70767

#제출 시각아이디문제언어결과실행 시간메모리
70767DiuvenTriangles (CEOI18_tri)C++14
100 / 100
1041 ms56124 KiB
#include <bits/stdc++.h> #include "trilib.h" using namespace std; typedef pair<int, int> pii; const int MX=40010; int n; map<pii, bool> mem[MX]; bool ccw(int a, int b, int c){ if(mem[a].find({b,c})!=mem[a].end()) return mem[a][pii(b,c)]; if(mem[a].find({c,b})!=mem[a].end()) return !mem[a][pii(c,b)]; return mem[a][pii(b,c)]=is_clockwise(a,b,c); } vector<int> L, R; vector<int> get_hull(int s, vector<int> V){ sort(V.begin(), V.end(), [=](int a, int b){ return ccw(s,a,b); }); vector<int> R; R.push_back(s); for(int v:V){ while(R.size()>=2U && !ccw(R[R.size()-2], R[R.size()-1], v)) R.pop_back(); R.push_back(v); } return R; } vector<int> all_hull(int v){ vector<int> V; for(int i=1; i<=n; i++) if(i!=v) V.push_back(i); return get_hull(v, V); } int solve(){ for(int i=3; i<=n; i++){ if(ccw(1,2,i)) R.push_back(i); else L.push_back(i); } if(L.empty() || R.empty()) return all_hull(1).size(); if(L.size()==1U) return all_hull(L[0]).size(); if(R.size()==1U) return all_hull(R[0]).size(); vector<int> LH, RH; LH=get_hull(1, L), RH=get_hull(2, R); int u=-1, v=-1, p=-1, q=-1; // upper tangent for(int p1=0, p2=0, lsz=LH.size(), rsz=RH.size(); p1<lsz; p1++){ while(true){ int a=(p2+rsz-1)%rsz, b=(p2+1)%rsz; if(!ccw(LH[p1], RH[p2], RH[a])){ p2=a; continue; } if(!ccw(LH[p1], RH[p2], RH[b])){ p2=b; continue; } break; } int a=(p1+lsz-1)%lsz, b=(p1+1)%lsz; if(ccw(RH[p2], LH[p1], LH[a])) continue; if(ccw(RH[p2], LH[p1], LH[b])) continue; assert(u<0 && v<0); u=p1, v=p2; break; } // lower tangent for(int p1=0, p2=0, lsz=LH.size(), rsz=RH.size(); p1<lsz; p1++){ while(true){ int a=(p2+rsz-1)%rsz, b=(p2+1)%rsz; if(ccw(LH[p1], RH[p2], RH[a])){ p2=a; continue; } if(ccw(LH[p1], RH[p2], RH[b])){ p2=b; continue; } break; } int a=(p1+lsz-1)%lsz, b=(p1+1)%lsz; if(!ccw(RH[p2], LH[p1], LH[a])) continue; if(!ccw(RH[p2], LH[p1], LH[b])) continue; assert(p<0 && q<0); p=p1, q=p2; break; } int cnt=0, pos; pos=v; while(true){ cnt++; if(pos==q) break; pos=(pos+1)%RH.size(); } pos=p; while(true){ cnt++; if(pos==u) break; pos=(pos+1)%LH.size(); } return cnt; } int main(){ n=get_n(); give_answer(solve()); return 0; }
#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...