Submission #232816

#TimeUsernameProblemLanguageResultExecution timeMemory
232816pedy4000Svjetlost (COI18_svjetlost)C++14
14 / 100
434 ms14968 KiB
#include <algorithm> #include <iostream> #include <iomanip> #include <vector> #include <cmath> #include <set> using namespace std; typedef long long ll; typedef long double ld; typedef pair <ll, ll> point; #define X first #define Y second point operator- (point a, point b) { return point(a.X - b.X, a.Y - b.Y); } ll operator* (point a, point b) { return a.X * b.Y - a.Y * b.X; } bool intersect (point a, point b, point c, point d) { point v = b - a, u = c - d; if (u * v == 0) return false; if (0 < (u * v)) return (u * v) <= ((a - d) * v); return (u * v) >= ((a - d) * v); } ld distance (point a, point b) { return sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y)); } const ll N = 1e5 + 5, inf = 1000000LL * 1000000LL; int n, q; point p[N]; ld res[N << 2]; ld lazy[N << 2]; ld len[N << 2]; set <int> live; int dist (int a, int b) { return a < b? b - a: n - a + b; } int nxt (int a) { if (live.lower_bound(a + 1) != live.end()) return *live.lower_bound(a + 1); return *live.begin(); } int prv (int a) { if (live.lower_bound(a) != live.begin()) return *(--live.lower_bound(a)); return *(--live.end()); } ld getLen (int l, int r, int s = 0, int e = n, int id = 1) { if (l <= s && e <= r) return len[id]; if (r <= s || e <= l) return 0; int mid = e + s >> 1; return getLen(l, r, s, mid, id << 1) + getLen(l, r, mid, e, id << 1 | 1); } void updLen (int tmp, ld val, int s = 0, int e = n, int id = 1) { if (e - s == 1) { len[id] = val; return ; } int mid = e + s >> 1; if (tmp < mid) updLen(tmp, val, s, mid, id << 1); else updLen(tmp, val, mid, e, id << 1 | 1); len[id] = len[id << 1] + len[id << 1 | 1]; } ld calcLen (int l, int r) { if (l <= r) return getLen(l, r + 1); return getLen(l, n) + getLen(0, r + 1); } int calc (int d) { int s = nxt(d), e = d; while (dist(s, e) > 1) { int mid = (s + dist(s, e) / 2) % n; if (intersect(p[d], p[nxt(d)], p[mid], p[nxt(mid)])) s = mid; else e = mid; } return s; } int calcRev (int d) { int s = d, e = prv(d); while (dist(s, e) > 1) { int mid = (s + dist(s, e) / 2) % n; if (intersect(p[mid], p[nxt(mid)], p[d], p[nxt(d)])) e = mid; else s = mid; } return e; } void buildLen (int s = 0, int e = n, int id = 1) { if (e - s == 1) { len[id] = distance(p[s], p[nxt(s)]); return ; } int mid = e + s >> 1; buildLen(s, mid, id << 1); buildLen(mid, e, id << 1 | 1); len[id] = len[id << 1] + len[id << 1 | 1]; } void buildResLst (int s = 0, int e = n, int id = 1) { if (e - s == 1) { res[id] = calcLen(s, calc(s)); return ; } int mid = e + s >> 1; buildResLst(s, mid, id << 1); buildResLst(mid, e, id << 1 | 1); res[id] = max(res[id << 1], res[id << 1 | 1]); } void preProcess() { for (int i = 0; i < n; i++) live.insert(i); buildLen(); buildResLst(); } void shift (int id) { res[id << 1] += lazy[id]; res[id << 1 | 1] += lazy[id]; lazy[id] = 0; } void setRes (int tmp, ld val, int s = 0, int e = n, int id = 1) { if (e - s == 1) { res[id] = val; return ; } if (lazy[id]) shift(id); int mid = e + s >> 1; if (tmp < mid) setRes(tmp, val, s, mid, id << 1); else setRes(tmp, val, mid, e, id << 1 | 1); res[id] = max(res[id << 1], res[id << 1 | 1]); } void updRes (int l, int r, ld val, int s = 0, int e = n, int id = 1) { if (l <= s && e <= r) { res[id] += val; lazy[id] += val; return ; } if (r <= s || e <= l) return ; if (lazy[id]) shift(id); int mid = e + s >> 1; updRes(l, r, val, s, mid, id << 1); updRes(l, r, val, mid, e, id << 1 | 1); res[id] = max(res[id << 1], res[id << 1 | 1]); } void calcRes (int l, int r, ld val) { if (l <= r) updRes(l, r + 1, val); else { updRes(l, n, val); updRes(0, r + 1, val); } } void delate (int id) { live.erase(id); int fr = nxt(id); int bc = prv(id); ld l1 = calcLen(bc, id); ld l2 = calcLen(id, fr); int K = calcRev(id); updLen(id, 0); updLen(bc, distance(p[bc], p[fr])); setRes(id, -inf); setRes(bc, calcLen(bc, calc(bc))); if (K != bc) calcRes(K, prv(bc), - distance(p[bc], p[id]) - distance(p[id], p[fr]) + distance(p[bc], p[fr])); if (calcRev(bc) != K) calcRes(calcRev(bc), prv(K), - distance(p[bc], p[id]) + distance(p[bc], p[fr])); } int main() { ios::sync_with_stdio(false), cin.tie(0); cin >> n; for (int i = 0; i < n; i++) cin >> p[i].X >> p[i].Y; preProcess(); cout << fixed << setprecision(6) << res[1] << "\n"; cin >> q; while (q--) { int id; cin >> id; id--; delate(id); cout << res[1] << "\n"; } return 0; }

Compilation message (stderr)

svjetlost.cpp: In function 'ld getLen(int, int, int, int, int)':
svjetlost.cpp:68:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'void updLen(int, ld, int, int, int)':
svjetlost.cpp:77:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'void buildLen(int, int, int)':
svjetlost.cpp:121:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'void buildResLst(int, int, int)':
svjetlost.cpp:133:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'void setRes(int, ld, int, int, int)':
svjetlost.cpp:161:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'void updRes(int, int, ld, int, int, int)':
svjetlost.cpp:181:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'void delate(int)':
svjetlost.cpp:200:5: warning: unused variable 'l1' [-Wunused-variable]
  ld l1 = calcLen(bc, id);
     ^~
svjetlost.cpp:201:5: warning: unused variable 'l2' [-Wunused-variable]
  ld l2 = calcLen(id, fr);
     ^~
#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...