Submission #232907

#TimeUsernameProblemLanguageResultExecution timeMemory
232907pedy4000Svjetlost (COI18_svjetlost)C++14
40 / 100
3035 ms19716 KiB
#include <algorithm> #include <iostream> #include <iomanip> #include <cassert> #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 = 10000000LL * 10000000LL; 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 cnt = 0; int s = nxt(d), e = d; while (nxt(s) != e) { cnt++; int mid = (s + dist(s, e) / 2) % n; if (nxt(mid) == e) mid = prv(nxt(mid)); else mid = nxt(prv(mid)); if (intersect(p[d], p[nxt(d)], p[mid], p[nxt(mid)])) s = mid; else e = mid; } assert(cnt <= 60); return s; } int calcRev (int d) { int s = d, e = prv(d); while (nxt(s) != e) { int mid = (s + dist(s, e) / 2) % n; if (nxt(mid) == e) mid = prv(nxt(mid)); else mid = nxt(prv(mid)); 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]; lazy[id << 1] += lazy[id]; res[id << 1 | 1] += lazy[id]; lazy[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) { int K2 = calcRev(prv(id)); live.erase(id); int fr = nxt(id); int bc = prv(id); int K = calcRev(id); int K3 = calcRev(bc); 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 (K3 != K) calcRes(K3, prv(K), - distance(p[bc], p[id]) + distance(p[bc], p[fr])); if (K2 != K3) calcRes(K2, prv(K3), - distance(p[bc], p[id])); } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%lld %lld", &p[i].X, &p[i].Y); preProcess(); printf("%5LF\n", res[1]); scanf("%d", &q); while (q--) { int id; scanf("%d", &id); id--; delate(id); printf("%5LF\n", res[1]); } 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:133:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'void buildResLst(int, int, int)':
svjetlost.cpp:145: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:176: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:196:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = e + s >> 1;
            ~~^~~
svjetlost.cpp: In function 'int main()':
svjetlost.cpp:234:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &n);
  ~~~~~^~~~~~~~~~
svjetlost.cpp:236:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%lld %lld", &p[i].X, &p[i].Y);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
svjetlost.cpp:240:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &q);
  ~~~~~^~~~~~~~~~
svjetlost.cpp:243:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &id);
   ~~~~~^~~~~~~~~~~
#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...