Submission #90697

#TimeUsernameProblemLanguageResultExecution timeMemory
90697jasony123123SIR (COI15_sir)C++11
100 / 100
304 ms13556 KiB
#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 (stderr)

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);
       ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...