Submission #927438

#TimeUsernameProblemLanguageResultExecution timeMemory
927438rainboyCell Automaton (JOI23_cell)C11
74 / 100
989 ms63816 KiB
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 300000 #define Q 500000 #define INF 0x7fffffff int abs_(int a) { return a > 0 ? a : -a; } int min(int a, int b) { return a < b ? a : b; } int max(int a, int b) { return a > b ? a : b; } unsigned int Z = 12345; int rand_() { return (Z *= 3) >> 1; } int xx[N], xx_[N], yy[N], yy_[N], uu[N], vv[N], tt_[N], n; int tt[Q]; long long ans[Q]; int q; int *ww; void sort(int *ii, int l, int r) { while (l < r) { int i = l, j = l, k = r, i_ = ii[l + rand_() % (r - l)], tmp; while (j < k) { int c = ww[ii[j]] != ww[i_] ? (ww[ii[j]] < ww[i_] ? -1 : 1) : (xx[ii[j]] != xx[i_] ? (xx[ii[j]] < xx[i_] ? -1 : 1) : 0); if (c == 0) j++; else if (c < 0) { tmp = ii[i], ii[i] = ii[j], ii[j] = tmp; i++, j++; } else { k--; tmp = ii[j], ii[j] = ii[k], ii[k] = tmp; } } sort(ii, l, i); l = k; } } void compress(int *xx, int *xx_, int n) { static int ii[N]; int i, x; for (i = 0; i < n; i++) ii[i] = i; ww = xx, sort(ii, 0, n); for (i = 0, x = 0; i < n; i++) xx_[ii[i]] = i + 1 == n || xx[ii[i + 1]] != xx[ii[i]] ? x++ : x; } int ft[N]; int min_(int i, int j) { return j == -1 || i != -1 && (vv[i] < vv[j] || vv[i] == vv[j] && i < j) ? i : j; } void update(int i, int n, int x) { while (i < n) { ft[i] = min_(ft[i], x); i |= i + 1; } } int query(int i) { int x = -1; while (i >= 0) { x = min_(x, ft[i]); i &= i + 1, i--; } return x; } int *ej[N], eo[N]; void append(int i, int j) { int o = eo[i]++; if (o >= 2 && (o & o - 1) == 0) ej[i] = (int *) realloc(ej[i], o * 2 * sizeof *ej[i]); ej[i][o] = j; } int aa[Q + 1]; long long bb[Q + 1]; void add(int t, int a, long long b) { int lower = -1, upper = q; while (upper - lower > 1) { int h = (lower + upper) / 2; if (tt[h] >= t) upper = h; else lower = h; } aa[upper] += a, bb[upper] += b; } int main() { static int ii[N], qu[N * 100], ii_[N * 100], jj_[N * 100]; int m, cnt, h, i, i_, j, j_, jl, jr, r, o, t, t_, tmp; long long u, u_, ul, ur; scanf("%d%d", &n, &q); for (i = 0; i < n; i++) scanf("%d%d", &xx[i], &yy[i]); for (h = 0; h < q; h++) scanf("%d", &tt[h]); for (i = 0; i < n; i++) uu[i] = xx[i] - yy[i], vv[i] = xx[i] + yy[i]; for (i = 0; i < n; i++) ej[i] = (int *) malloc(2 * sizeof *ej[i]), eo[i] = 0; compress(xx, xx_, n), compress(yy, yy_, n); for (r = 0; r < 4; r++) { for (i = 0; i < n; i++) ii[i] = i; ww = uu, sort(ii, 0, n); memset(ft, -1, n * sizeof *ft); for (i = 0; i < n; i = j) { j = i + 1; while (j < n && uu[ii[j]] == uu[ii[i]]) j++; for (h = i; h < j; h++) { i_ = ii[h], j_ = query(n - 1 - xx_[i_]); if (j_ != -1) append(i_, j_), append(j_, i_); update(n - 1 - xx_[i_], n, i_); } cnt = 0; for (h = i; h < j; h++) { i_ = ii[h]; while (cnt && qu[cnt - 1] > i_) cnt--; if (cnt) { j_ = qu[cnt - 1]; append(i_, j_), append(j_, i_); } qu[cnt++] = i_; } } memset(ft, -1, n * sizeof *ft); for (j = n; j > 0; j = i) { i = j - 1; while (i > 0 && uu[ii[i - 1]] == uu[ii[j - 1]]) i--; for (h = i; h < j; h++) { i_ = ii[h], j_ = query(n - 1 - yy_[i_]); if (j_ != -1) append(i_, j_), append(j_, i_); update(n - 1 - yy_[i_], n, i_); } } for (i = 0; i < n; i++) { tmp = xx[i], xx[i] = -yy[i], yy[i] = tmp; tmp = xx_[i], xx_[i] = n - 1 - yy_[i], yy_[i] = tmp; tmp = uu[i], uu[i] = -vv[i], vv[i] = tmp; } } for (i = 0; i < n; i++) { for (o = 0; o < eo[i]; o++) { j = ej[i][o]; tt_[j] = ((long long) abs_(xx[j] - xx[i]) + abs_(yy[j] - yy[i]) + (i < j ? 2 : 1)) / 2; } ww = tt_, sort(ej[i], 0, eo[i]); } m = 0; for (r = 0; r < 4; r++) { for (i = 0; i < n; i++) { u = uu[i], ul = -INF, jl = -1, ur = INF, jr = -1, t_ = -1, cnt = 0; for (o = 0; o < eo[i]; o++) { j = ej[i][o], t = ((long long) abs_(xx[j] - xx[i]) + abs_(yy[j] - yy[i]) + (i < j ? 2 : 1)) / 2; if (vv[j] < vv[i] || vv[j] == vv[i] && j > i) { if (vv[j] == vv[i]) qu[cnt++] = j; continue; } if (ul != -INF && ur != INF && ul + t > ur - t + 1 && t != t_) break; t_ = t; if (uu[j] < u) { u_ = uu[j] + (i < j ? 0 : 1); if (ul == -INF) { ul = u_, jl = j; for (h = 0; h < cnt; h++) ii_[m] = qu[h], jj_[m] = j, m++; } else { ul = max(ul, u_); if (uu[jl] < uu[j] || uu[jl] == uu[j] && jl > j) jl = j; } } else { u_ = uu[j] - (i < j ? 0 : 1); if (ur == INF) { ur = u_, jr = j; for (h = 0; h < cnt; h++) ii_[m] = qu[h], jj_[m] = j, m++; } else { ur = min(ur, u_); if (uu[jr] > uu[j] || uu[jr] == uu[j] && jr > j) jr = j; } } } if (jl != -1 && jr != -1) ii_[m] = jl, jj_[m] = jr, m++; } for (i = 0; i < n; i++) { tmp = xx[i], xx[i] = -yy[i], yy[i] = tmp; tmp = uu[i], uu[i] = -vv[i], vv[i] = tmp; } } for (h = 0; h < m; h++) { i = ii_[h], j = jj_[h]; append(i, j), append(j, i); } for (i = 0; i < n; i++) { for (o = 0; o < eo[i]; o++) { j = ej[i][o]; tt_[j] = ((long long) abs_(xx[j] - xx[i]) + abs_(yy[j] - yy[i]) + (i < j ? 2 : 1)) / 2; } ww = tt_, sort(ej[i], 0, eo[i]); } for (r = 0; r < 4; r++) { for (i = 0; i < n; i++) { add(0, 1, 0); u = uu[i], ul = -INF, ur = INF, t = INF; for (o = 0; o <= eo[i]; o++) { if (o == eo[i]) { t = ul != -INF && ur != INF ? (ur - ul) / 2 + 1 : INF; break; } j = ej[i][o], t = ((long long) abs_(xx[j] - xx[i]) + abs_(yy[j] - yy[i]) + (i < j ? 2 : 1)) / 2; if (vv[j] < vv[i] || vv[j] == vv[i] && j > i) continue; if (ul != -INF && ur != INF && ul + t > ur - t) { t = (ur - ul) / 2 + 1; break; } if (uu[j] < u) { u_ = uu[j] + (i < j ? 0 : 1); if (ul == -INF) add(t, -1, (u - u_) / 2), ul = u_; else if (ul < u_) add(t, 0, (u - u_) / 2 - (u - ul) / 2), ul = u_; } else { u_ = uu[j] - (i < j ? 0 : 1); if (ur == INF) add(t, -1, (u_ - u + 2) / 2), ur = u_; else if (ur > u_) add(t, 0, (u_ - u + 2) / 2 - (ur - u + 2) / 2), ur = u_; } if (ul != -INF && ur != INF && ul + t > ur - t) break; } if (t != INF) add(t, 1, -((u - ul) / 2 + (ur - u + 2) / 2)); } for (i = 0; i < n; i++) { tmp = xx[i], xx[i] = -yy[i], yy[i] = tmp; tmp = uu[i], uu[i] = -vv[i], vv[i] = tmp; } } for (h = 1; h < q; h++) aa[h] += aa[h - 1], bb[h] += bb[h - 1]; for (h = 0; h < q; h++) ans[h] = tt[h] == 0 ? n : (long long) aa[h] * tt[h] + bb[h]; for (h = 0; h < q; h++) printf("%lld\n", ans[h]); return 0; }

Compilation message (stderr)

cell.c: In function 'min_':
cell.c:60:64: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   60 |  return j == -1 || i != -1 && (vv[i] < vv[j] || vv[i] == vv[j] && i < j) ? i : j;
      |                                                 ~~~~~~~~~~~~~~~^~~~~~~~
cell.c:60:28: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   60 |  return j == -1 || i != -1 && (vv[i] < vv[j] || vv[i] == vv[j] && i < j) ? i : j;
      |                    ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cell.c: In function 'append':
cell.c:85:23: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
   85 |  if (o >= 2 && (o & o - 1) == 0)
      |                     ~~^~~
cell.c: In function 'main':
cell.c:179:41: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  179 |     if (vv[j] < vv[i] || vv[j] == vv[i] && j > i) {
      |                          ~~~~~~~~~~~~~~~^~~~~~~~
cell.c:195:45: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  195 |       if (uu[jl] < uu[j] || uu[jl] == uu[j] && jl > j)
      |                             ~~~~~~~~~~~~~~~~^~~~~~~~~
cell.c:206:45: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  206 |       if (uu[jr] > uu[j] || uu[jr] == uu[j] && jr > j)
      |                             ~~~~~~~~~~~~~~~~^~~~~~~~~
cell.c:240:41: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  240 |     if (vv[j] < vv[i] || vv[j] == vv[i] && j > i)
      |                          ~~~~~~~~~~~~~~~^~~~~~~~
cell.c:111:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  111 |  scanf("%d%d", &n, &q);
      |  ^~~~~~~~~~~~~~~~~~~~~
cell.c:113:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  113 |   scanf("%d%d", &xx[i], &yy[i]);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cell.c:115:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  115 |   scanf("%d", &tt[h]);
      |   ^~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...