Submission #591568

#TimeUsernameProblemLanguageResultExecution timeMemory
591568TemmieWombats (IOI13_wombats)C++17
12 / 100
237 ms96584 KiB
#include "wombats.h" #include <bits/stdc++.h> constexpr const int BS = 20; constexpr const int mxr = 5000; constexpr const int mxc = 200; constexpr const int mxv = 0b01111111; int r, c; unsigned int h[mxr][mxc]; unsigned int v[mxr][mxc]; struct Block { int sc = -1, ec = -1; unsigned int con[mxc][mxc]; void update(int _sc, int _ec) { sc = _sc; ec = _ec; memset(con, mxv, sizeof(con)); for (int j = 0; j < c; j++) { con[j][j] = 0; } static unsigned int nxt[mxc][mxc]; for (int i = ec; i >= sc; i--) { memset(nxt, mxv, sizeof(nxt)); if (i == ec) { for (int j = 0; j < c; j++) { nxt[j][j] = 0; } } for (int j = 0; j < c; j++) { if (i != ec) { for (int k = 0; k < c; k++) { nxt[j][k] = std::min(nxt[j][k], con[j][k] + v[i][j]); } } if (j) { for (int k = 0; k < c; k++) { nxt[j][k] = std::min(nxt[j][k], nxt[j - 1][k] + h[i][j - 1]); } } } for (int j = c - 1; j >= 0; j--) { if (j + 1 < c) { for (int k = 0; k < c; k++) { nxt[j][k] = std::min(nxt[j][k], nxt[j + 1][k] + h[i][j]); } } } memcpy(con, nxt, sizeof(nxt)); } } void merge(const Block* upper, const Block* lower) { if (upper && !lower) { sc = upper->sc; ec = upper->ec; memcpy(con, upper->con, sizeof(upper->con)); return; } if (!upper) { assert(!lower); return; } sc = upper->sc; ec = lower->ec; assert(upper->ec + 1 < r); static unsigned int bes[mxc][mxc]; memset(con, mxv, sizeof(con)); memset(bes, mxv, sizeof(bes)); for (int d = -c - 1; d < c; d++) { for (int i = std::max(0, -d); i + std::max(0, d) < c; i++) { int j = i + d; int l = 0; int r = c - 1; if (j && con[i][j - 1] < 1000) { l = con[i][j - 1]; } if (i + 1 < c && con[i + 1][j] < 1000) { r = con[i + 1][j]; } con[i][j] = mxv; for (int k = l; k <= r; k++) { if (upper->con[i][k] + lower->con[k][j] + v[upper->ec][k] < con[i][j]) { con[i][j] = upper->con[i][k] + lower->con[k][j] + v[upper->ec][k]; bes[i][j] = k; } } } } } }; struct Seg { int size; std::vector <Block*> v; Seg(int s) { size = 1; while (size < s) { size <<= 1; } v.resize(size << 1, nullptr); build(0, 0, size); } void build(int now, int li, int ri) { if (!(ri - li - 1)) { if (li * BS < r) { v[now] = new Block(); v[now]->update(li * BS, std::min(r - 1, (li + 1) * BS - 1)); } return; } int mid = (li + ri) >> 1; build(now * 2 + 1, li, mid); build(now * 2 + 2, mid, ri); if (v[now * 2 + 1]) { v[now] = new Block(); v[now]->merge(v[now * 2 + 1], v[now * 2 + 2]); } } void update(int ind) { update(ind, 0, 0, size); } void update(int ind, int now, int li, int ri) { if (!(ri - li - 1)) { v[now]->update(ind * BS, std::min(r - 1, (ind + 1) * BS - 1)); return; } int mid = (li + ri) >> 1; if (ind < mid) { update(ind, now * 2 + 1, li, mid); } else { update(ind, now * 2 + 2, mid, ri); } if (v[now]) { v[now]->merge(v[now * 2 + 1], v[now * 2 + 2]); } } }; Seg* seg; void init(int R, int C, int H[5000][200], int V[5000][200]) { r = R; c = C; memcpy(h, H, sizeof(h)); memcpy(v, V, sizeof(v)); seg = new Seg((r + BS - 1) / BS); } void changeH(int p, int q, int w) { h[p][q] = w; seg->update(p / BS); } void changeV(int p, int q, int w) { v[p][q] = w; seg->update(p / BS); } int escape(int v1, int v2) { return seg->v[0]->con[v1][v2]; }

Compilation message (stderr)

grader.c: In function 'int main()':
grader.c:15:6: warning: variable 'res' set but not used [-Wunused-but-set-variable]
   15 |  int res;
      |      ^~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...