Submission #246306

#TimeUsernameProblemLanguageResultExecution timeMemory
246306eohomegrownappsTriangles (CEOI18_tri)C++14
100 / 100
338 ms47756 KiB
#include "trilib.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
int get_n();
int is_clockwise(int a, int b, int c);
void give_answer(int s);
*/
 
int n;
 
int cns = 40000;
unordered_map<int,bool> cwmap[40000];
int numhashed = 0;
 
bool cwhash(int a, int b, int c){
	int ct = b*cns+c;
	auto f = cwmap[a].find(ct);
	if (f!=cwmap[a].end()){
		return cwmap[a][ct];
	} else {
		if (numhashed<=1000000){
			numhashed++;
			return cwmap[a][ct]=bool(is_clockwise(a+1,b+1,c+1));
		} else {
			return bool(is_clockwise(a+1,b+1,c+1));
		}
	}
}
 
bool cw(int a, int b, int c){
	//cout<<"cw "<<a<<" "<<b<<" "<<c<<" ";
	int minv = min(min(a,b),c);
	int tmp;
	if (a!=minv){
		tmp=a;a=b;b=c;c=tmp;
	}
	if (a!=minv){
		tmp=a;a=b;b=c;c=tmp;
	}
	if (b<c){
		return cwhash(a,b,c);
	} else {
		return !cwhash(a,c,b);
	}
	//cout<<ans<<'\n';
}
/*int pcnt = 0;
bool cw(int a, int b, int c){
	pcnt++;
	assert(pcnt<=1000000);
	return is_clockwise(a+1,b+1,c+1);
}*/
 
vector<int> pts;
vector<int> rhs;
vector<int> lhs;
vector<int> hull;
int convexhull(int s, int e){
	/*cout<<s<<" "<<e<<'\n';
	cout<<"find hull ";
	for (int i = s; i<e; i++){
		cout<<pts[i]<<" ";
	}cout<<'\n';*/
	if (e-s<=3){
		if (e-s==3&&!cw(pts[s],pts[s+1],pts[s+2])){
			swap(pts[s+1],pts[s+2]);
		}
		return e-s;
	}
	int a = pts[s];
	int b = pts[s+1];
	//a to b
	lhs.clear();
	rhs.clear();
	for (int i = s+2; i<e; i++){
		if (cw(a,b,pts[i])){
			lhs.push_back(pts[i]);
		} else {
			rhs.push_back(pts[i]);
		}
	}
	if (lhs.size()>rhs.size()){
		swap(lhs,rhs);
		swap(a,b);
	}
	lhs.push_back(a);
	lhs.push_back(b);
	assert(s+lhs.size()+rhs.size()==e);
	for (int i = s; i<s+lhs.size(); i++){
		pts[i]=lhs[i-s];
	}
	for (int i = s+lhs.size(); i<e; i++){
		pts[i]=rhs[i-s-lhs.size()];
	}
	/*cout<<"lhs: ";
	for (int i : lhs){
		cout<<i<<" ";
	}cout<<'\n';
	cout<<"rhs: ";
	for (int i : rhs){
		cout<<i<<" ";
	}cout<<'\n';
	for (int i : pts){
		cout<<i<<" ";
	}cout<<'\n';*/
	int rf = rhs.size();
	int lf = lhs.size();
	int ls = convexhull(s,s+lf);
	int rs = convexhull(s+lf,e);
	/*cout<<"merge:\n";
	for (int i = s; i<s+ls; i++){
		cout<<pts[i]<<" ";
	}cout<<'\n';
	for (int j = s+lf;j<s+lf+rs; j++){
		cout<<pts[j]<<" ";
	}cout<<'\n';*/
	//now in sorted order
	int leftpt = b;
	
	int rightpt = pts[s+lf];
	int leftind = -1;
	int rightind = 0;
	for (int i = 0; i<rs; i++){
		if (rf>1&&cw(pts[s+lf+(i+1)%rs],pts[s+lf+i],leftpt)){
			rightpt=pts[s+lf+i];
			rightind = i;
			break;
		}
	}
	assert(rightpt!=-1);
	leftind = find(pts.begin()+s,pts.begin()+s+lf,leftpt)-(pts.begin()+s);
	//cout<<leftpt<<" "<<rightpt<<'\n';
	//cout<<leftind<<" "<<rightind<<'\n';
	int lp2 = leftind;
	int rp1 = rightind;
	bool check;
	bool condexit;
	do {
		check = true;
		condexit = true;
		while (ls>1&&!cw(pts[s+lf+rp1],pts[s+lp2],pts[s+(lp2+1)%ls])){
			if (ls>1&&rs>1&&!cw(pts[s+(lp2+1)%ls],pts[s+lf+rp1],pts[s+lf+(rp1+rs-1)%rs])&&cw(pts[s+lf+rp1],pts[s+lf+(rp1+rs-1)%rs],pts[s+lp2])){
				//check=false;
				condexit = false;
				break;
			}
			//cout<<"inc lp2\n";
			lp2+=1;
			lp2%=ls;
			check = false;
		}
		while (rs>1&&cw(pts[s+lp2],pts[s+lf+rp1],pts[s+lf+(rp1+rs-1)%rs])){
			if (ls>1&&rs>1&&cw(pts[s+lf+(rp1+rs-1)%rs],pts[s+lp2],pts[s+(lp2+1)%ls])&&!cw(pts[s+lp2],pts[s+(lp2+1)%ls],pts[s+lf+rp1])){
				//check=false;
				condexit = false;
				break;
			}
			//cout<<"dec rp1\n";
			rp1+=rs-1;
			rp1%=rs;
			check = false;
		}
	} while (!check);
	assert(condexit==true);
	int lp1 = leftind;
	int rp2 = rightind;
	do {
		check = true;
		condexit = true;
		while (ls>1&&cw(pts[s+lf+rp2],pts[s+lp1],pts[s+(lp1+ls-1)%ls])){
			//cout<<"vis\n";
			//cout<<pts[s+lp1]<<" "<<pts[s+ls+rp2]<<'\n';
			if (ls>1&&rs>1&&cw(pts[s+(lp1+ls-1)%ls],pts[s+lf+rp2],pts[s+lf+(rp2+1)%rs])&&!cw(pts[s+lf+rp2],pts[s+lf+(rp2+1)%rs],pts[s+lp1])){
				//check=false;
				condexit = false;
				break;
			}
			//cout<<"dec lp1\n";
			lp1+=ls-1;
			lp1%=ls;
			check = false;
		}
		while (rs>1&&!cw(pts[s+lp1],pts[s+lf+rp2],pts[s+lf+(rp2+1)%rs])){
			if (ls>1&&rs>1&&!cw(pts[s+lf+(rp2+1)%rs],pts[s+lp1],pts[s+(lp1+ls-1)%ls])&&cw(pts[s+lp1],pts[s+(lp1+ls-1)%ls],pts[s+lf+rp2])){
				//check=false;
				condexit = false;
				break;
			}
			//cout<<"inc rp2\n";
			rp2+=1;
			rp2%=rs;
			check = false;
		}
	} while (!check);
	assert(condexit==true);
	//cout<<pts[s+lp1]<<" "<<pts[s+lp2]<<'\n';
	//cout<<pts[s+ls+rp1]<<" "<<pts[s+ls+rp2]<<'\n';
	hull.clear();
	int ptr;
	ptr = rp2;
	while (ptr!=rp1) {
		hull.push_back(pts[s+lf+ptr]);
		ptr++;
		ptr%=rs;
	}
	hull.push_back(pts[s+lf+ptr]);
	ptr = lp2;
	while (ptr!=lp1) {
		hull.push_back(pts[s+ptr]);
		ptr++;
		ptr%=ls;
	}
	hull.push_back(pts[s+ptr]);
	for (int i = s; i<s+hull.size(); i++){
		pts[i]=hull[i-s];
	}
	
	/*cout<<"hull contains ";
	for (int i : hull){
		cout<<i<<' ';
	}cout<<'\n';*/
	int hs = hull.size();
	return hs;
}
 
int main(){
	n = get_n();
	pts.resize(n);
	iota(pts.begin(),pts.end(),0);
    std::mt19937 g(1234588);
	shuffle(pts.begin(),pts.end(),g);
	give_answer(convexhull(0,n));
}

Compilation message (stderr)

In file included from /usr/include/c++/7/cassert:44:0,
                 from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:33,
                 from tri.cpp:2:
tri.cpp: In function 'int convexhull(int, int)':
tri.cpp:90:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  assert(s+lhs.size()+rhs.size()==e);
         ~~~~~~~~~~~~~~~~~~~~~~~^~~
tri.cpp:91:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = s; i<s+lhs.size(); i++){
                  ~^~~~~~~~~~~~~
tri.cpp:216:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = s; i<s+hull.size(); i++){
                  ~^~~~~~~~~~~~~~
#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...