답안 #90697

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
90697 2018-12-23T17:34:05 Z jasony123123 SIR (COI15_sir) C++11
100 / 100
304 ms 13556 KB
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;

#define FOR(i,start,end) for(int i=start;i<(int)(end);i++)
#define FORE(i,start,end) for(int i=start;i<=(int)end;i++)
#define RFOR(i,start,end) for(int i = start; i>end; i--)
#define RFORE(i,start,end) for(int i = start; i>=end; i--)
#define all(a) a.begin(), a.end()
#define mt make_tuple
#define mp make_pair
#define v vector
#define sf scanf
#define pf printf
#define dvar(x) cout << #x << " := " << x << "\n"
#define darr(x,n) FOR(i,0,n) cout << #x << "[" << i << "]" << " := " << x[i] << "\n"

typedef long long ll;
typedef long double ld;
typedef pair<int, int > pii;
typedef pair<ll, ll> pll;
//template <class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<class T> void minn(T &a, T b) { a = min(a, b); }
template<class T> void maxx(T &a, T b) { a = max(a, b); }

void io() {
#ifdef LOCAL_PROJECT 
	freopen("input.in", "r", stdin); freopen("output.out", "w", stdout);
#else 
	/* online submission */

#endif 
	ios_base::sync_with_stdio(false); cin.tie(NULL);
}

const ll MOD = 1000000007LL;
const ll PRIME = 105943LL;
const ll INF = 1e18;
/****************************************************************/
const int SZ = 1e6;
struct DynamicArea {
	ll sum = 0;
	ll data[SZ][3];
	int f = 0, b = -1;

	void init(pll p) {
		b++;
		assert(b < SZ);
		data[b][0] = p.first;
		data[b][1] = p.second;
		data[b][2] = 0;
	}
	ll calc(pll a, pll b) {
		return a.second*b.first - a.first*b.second;
	}
	void push_back(pll p) {
		b++;
		assert(b < SZ);
		data[b][0] = p.first;
		data[b][1] = p.second;
		data[b][2] = calc({ data[b - 1][0], data[b - 1][1] }, p);
		sum += data[b][2];
	}
	void pop_front() {
		f++;
		assert(f <= b);
		sum -= data[f][2];
	}
	ll query() {
		return abs(sum + calc({ data[b][0], data[b][1] }, { data[f][0], data[f][1] }));
	}
};

ll cross(const pll &O, const pll &A, const pll &B) {
	return ((ll)(A.first - O.first)) * (B.second - O.second) - ((ll)(A.second - O.second)) * (B.first - O.first);
}
v<pll> convex_hull(v<pll> &P) {
	sort(P.begin(), P.end()); P.erase(unique(P.begin(), P.end()), P.end());
	int n = P.size();
	if (n == 1) return P;
	v<pll> bot = { P[0] };
	FOR(i, 1, n) {
		while (bot.size() > 1 && cross(bot[bot.size() - 2], bot.back(), P[i]) <= 0) bot.pop_back();
		bot.push_back(P[i]);
	}
	bot.pop_back();
	v<pll> up = { P[n - 1] };
	RFORE(i, n - 1, 0) {
		while (up.size() > 1 && cross(up[up.size() - 2], up.back(), P[i]) <= 0) up.pop_back();
		up.push_back(P[i]);
	}
	up.pop_back();
	bot.insert(bot.end(), up.begin(), up.end());
	return bot;
}

#define X first
#define Y second
typedef pair<ll, ll> Point;
typedef pair<ll, ll> Vector;

Vector make_Vector(Point a, Point b) {
	return make_pair(a.X - b.X, a.Y - b.Y); // a <--- b
}
ll dot(Vector u, Vector v) {
	return ((u).X * (v).X + (u).Y * (v).Y);
}
bool up(Vector u, Vector v) {
	return (dot(u, v) > 0);
}
bool down(Vector u, Vector v) {
	return (dot(u, v) < 0);
}
ll dr(Vector u, Point Vi, Point Vj) {
	return dot(u, make_Vector(Vi, Vj)); // direction sign of (Vi-Vj)
}
bool above(Vector u, Point Vi, Point Vj) {
	return (dr(u, Vi, Vj) > 0);   // true if Vi is above Vj
}
bool below(Vector u, Point Vi, Point Vj) {
	return (dr(u, Vi, Vj) < 0);   // true if Vi is below Vj
}
/*
direction vector, CCW set of polygon points, were [n]==[0]
and n - the number of actual distint points
RETURNS the maximum point in that direction idx
in logn time
*/
int polyMax_2D(Vector dir_vector, vector<Point>& poly_points, int n) {
	int     point_a_idx, point_b_idx, point_c_idx;
	Vector  edge_a_vector, edge_c_vector;
	int     is_up_edgeA, is_up_edgeC;
	point_a_idx = 0;
	point_b_idx = n;
	edge_a_vector = make_Vector(poly_points[1], poly_points[0]);
	is_up_edgeA = up(dir_vector, edge_a_vector);
	if (!is_up_edgeA && !above(dir_vector, poly_points[n - 1], poly_points[0])) return 0;
	while(1) {
		point_c_idx = (point_a_idx + point_b_idx) >> 1;
		edge_c_vector = make_Vector(poly_points[point_c_idx + 1], poly_points[point_c_idx]);
		is_up_edgeC = up(dir_vector, edge_c_vector);
		if (!is_up_edgeC && !above(dir_vector, poly_points[point_c_idx - 1], poly_points[point_c_idx]))	return point_c_idx;
		if (is_up_edgeA)
			if (!is_up_edgeC) point_b_idx = point_c_idx;
			else
				if (above(dir_vector, poly_points[point_a_idx], poly_points[point_c_idx])) point_b_idx = point_c_idx;
				else point_a_idx = point_c_idx, edge_a_vector = edge_c_vector, is_up_edgeA = is_up_edgeC;
		else
			if (is_up_edgeC) point_a_idx = point_c_idx, edge_a_vector = edge_c_vector, is_up_edgeA = is_up_edgeC;
			else
				if (below(dir_vector, poly_points[point_a_idx], poly_points[point_c_idx]))	point_b_idx = point_c_idx;
				else point_a_idx = point_c_idx, edge_a_vector = edge_c_vector, is_up_edgeA = is_up_edgeC;
		if (point_b_idx <= point_a_idx + 1) return -1;
	}
	return -1;
}
int halfplane(Point p, ll a, ll b, ll c) {
	ll res = a*p.X + b*p.Y - c;
	if (res > 0)
		return 1;
	else if (res == 0)
		return 0;
	else
		return -1;
}
int doesIntersect(ll a, ll b, ll c, v<pll> &hull) {
	if (hull.size()-1 == 1) {
		int hp = halfplane(hull[0], a, b, c);
		return hp;
	}
	else if (hull.size() - 1 == 2) {
		int hp = halfplane(hull[0], a, b, c);
		int hp2 = halfplane(hull[1], a, b, c);
		if (hp == 0 || halfplane(hull[1], a, b, c) != hp)
			return 0;
		return hp;
	}
	Point extr1, extr2;
	extr1 = hull[polyMax_2D(make_pair(a, b), hull, hull.size() - 1)];
	extr2 = hull[polyMax_2D(make_pair(-a, -b), hull, hull.size() - 1)];
	int hp = halfplane(extr1, a, b, c);
	if (hp == 0 || halfplane(extr2, a, b, c) != hp)
		return 0;
	return hp;
}

int N, M;
v<pll> cHull, pHull;

int intersect(int i, int j) { // return 0 i->j intersects with pepper hull, 1, -1 = halfplane pepper hull is on, 
	ll xi = cHull[i].first, yi = cHull[i].second, xj = cHull[j].first, yj = cHull[j].second;
	ll A = yi - yj;
	ll B = xj - xi;
	ll C = (xj - xi)*yi - (yj - yi)*xi;
	return doesIntersect(A, B, C, pHull);
}

void input() {
	cin >> N;
	cHull.resize(N);
	FOR(i, 0, N) cin >> cHull[i].first >> cHull[i].second;
	cHull = convex_hull(cHull);
	cin >> M;
	pHull.resize(M);
	FOR(i, 0, M) cin >> pHull[i].first >> pHull[i].second;
	if (pHull.size() > 3)
		pHull = convex_hull(pHull);
	pHull.push_back(pHull[0]);
	//for (pll a : pHull)
	//	cout << a.first << " " << a.second << "\n";
}

DynamicArea da;

int main() {
	io();
	input();
	da.init(cHull[0]);
	ll ans = 0;
	for (int i = 0, j = 0; i < N; i++) {
		int correct = intersect(i, (i + 1) % N);
		while (((j + 1) % N) != ((i - 1 + N) % N) && intersect(i, (j + 1) % N) == correct){
			j = (j + 1) % N;
			da.push_back(cHull[j]);
		}
	//	cout << i << " to " << j << "\n";
		if (i != j && ((i + 1) % N) != j) {
	//		cout << da.query() << "\n";
			maxx(ans, da.query());
		}
		da.pop_front();
	}
	cout << ans << "\n";
	return 0;
}

Compilation message

sir.cpp: In function 'int doesIntersect(ll, ll, ll, std::vector<std::pair<long long int, long long int> >&)':
sir.cpp:176:7: warning: unused variable 'hp2' [-Wunused-variable]
   int hp2 = halfplane(hull[1], a, b, c);
       ^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 376 KB Output is correct
2 Correct 2 ms 432 KB Output is correct
3 Correct 2 ms 432 KB Output is correct
4 Correct 2 ms 432 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 608 KB Output is correct
2 Correct 3 ms 736 KB Output is correct
3 Correct 6 ms 904 KB Output is correct
4 Correct 3 ms 904 KB Output is correct
5 Correct 3 ms 904 KB Output is correct
6 Correct 3 ms 936 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 304 ms 13556 KB Output is correct
2 Correct 282 ms 13556 KB Output is correct
3 Correct 236 ms 13556 KB Output is correct
4 Correct 64 ms 13556 KB Output is correct
5 Correct 219 ms 13556 KB Output is correct
6 Correct 167 ms 13556 KB Output is correct