Submission #287458

# Submission time Handle Problem Language Result Execution time Memory
287458 2020-08-31T17:08:52 Z Namnamseo Tri (CEOI09_tri) C++17
80 / 100
637 ms 65540 KB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pp;
void read(int& x){ scanf("%d",&x); }
template<typename T,typename... Args>
void read(T& a,Args&... b){ read(a); read(b...); }
#define all(x) (x).begin(),(x).end()
#define pb push_back

#define x first
#define y second

vector<pp> kpt;
ll inf = 1LL << 60;
int kn, qn;

pp operator-(pp a, pp b){
	return pp{a.first-b.first, a.second-b.second};
}

ll cross(pp a, pp b){
	return b.y*1LL*a.x - b.x*1LL*a.y;
}

ll cross(pp a, pp b, pp c){ return cross(b-a, c-a); }

void in(){
    int k;
    read(k, qn); kpt.resize(k);
    for(auto& tmp:kpt){
		int a,b; read(a,b); tmp={a, b};
    }
}

void soka(){
    sort(all(kpt), [&](const pp& a, const pp& b){
		ll tmp=cross(a, b);
		if(tmp != 0) return tmp > 0;
		return a.x < b.x;
	});
    kpt.erase(unique(all(kpt), [&](const pp& a, const pp& b){
		return cross(a, b) == 0LL;
	}), kpt.end());
	kn = kpt.size();
}

struct hside {
	vector<pp> pts;
	int n;
	ll min_jub(pp grad){
		int l=0, r=n-1;
		while(l+3 < r){
			int p1=(l*2+r)/3;
			int p2=(l+2*r)/3;
			ll v1=(-grad.y)*1LL*pts[p1].x + grad.x*1LL*pts[p1].y;
			ll v2=(-grad.y)*1LL*pts[p2].x + grad.x*1LL*pts[p2].y;
			if(v1 > v2) l=p1; else r=p2;
		}
		ll ret=inf;
		for(int i=l; i<=r; ++i){
			auto& tmp=pts[i];
			ret=min(ret, (-grad.y)*1LL*tmp.x + grad.x*1LL*tmp.y);
		}
		return ret;
	}
};

struct hull {
	vector<pp> pt;
	void add_pt(pp& x){ pt.pb(x); }
	hside uh, dh;
	void build(){
		sort(all(pt));
		vector<pp>& uv=uh.pts; int& un=uh.n;
		vector<pp>& dv=dh.pts; int& dn=dh.n;
		un=0;
		for(pp& tmp:pt){
			while(un >= 2 && cross(uv[un-2], uv[un-1], tmp)>=0) uv.pop_back(), --un;
			uv.pb(tmp); ++un;
		}
		reverse(all(pt));
		dn=0;
		for(pp& tmp:pt){
			while(dn >= 2 && cross(dv[dn-2], dv[dn-1], tmp)>=0) dv.pop_back(), --dn;
			dv.pb(tmp); ++dn;
		}
		pt.clear();
	}
	ll min_jub(pp grad){
		return dh.min_jub(grad);
	}
};

struct hnode {
	hull h;
	hnode *lp, *rp;
	int l, r;
	hnode(int a, int b){
		l=a; r=b;
		for(int i=l; i<=r; ++i) h.add_pt(kpt[i]);
		h.build();
		if(l != r){
			int mid=(l+r)/2;
			lp=new hnode(l, mid);
			rp=new hnode(mid+1, r);
		}
	}
	
	ll min_jub(int ql, int qr, pp grad){
		if(ql <= l && r <= qr) return h.min_jub(grad);
		else if(r<ql || qr<l) return inf;
		return min(lp->min_jub(ql, qr, grad), rp->min_jub(ql, qr, grad));
	}
} *root;

auto ccw = [](pp a, pp b){ return cross(a, b) > 0; };

int main() {
	in();
	soka();
	root = new hnode(0, kn-1);
	for(;qn--;){
		pp a, b; read(a.x, a.y); read(b.x, b.y);
		if(ccw(b, a)) swap(a, b);
		int pl = upper_bound(all(kpt), a, ccw) - kpt.begin();
		int pr = lower_bound(all(kpt), b, ccw) - kpt.begin();
		if(pl == pr){
			puts("N"); continue;
		}
		pp grad = a-b;
		ll cur = (-grad.y)*1LL*b.x + (grad.x)*1LL*b.y;
		if(root->min_jub(pl, pr-1, grad) > cur) puts("N");
		else puts("Y");
	}
    return 0;
}

Compilation message

tri.cpp: In function 'void read(int&)':
tri.cpp:5:25: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    5 | void read(int& x){ scanf("%d",&x); }
      |                    ~~~~~^~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 3 ms 896 KB Output is correct
2 Correct 3 ms 896 KB Output is correct
3 Correct 101 ms 18916 KB Output is correct
4 Correct 175 ms 35832 KB Output is correct
5 Runtime error 275 ms 65540 KB Execution killed with signal 9
6 Correct 494 ms 55288 KB Output is correct
7 Correct 637 ms 65536 KB Output is correct
8 Correct 517 ms 59920 KB Output is correct
9 Correct 586 ms 65536 KB Output is correct
10 Runtime error 227 ms 65540 KB Execution killed with signal 9