Submission #927315

# Submission time Handle Problem Language Result Execution time Memory
927315 2024-02-14T17:45:01 Z rainboy Cell Automaton (JOI23_cell) C
58 / 100
500 ms 38500 KB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N	100000
#define Q	500000
#define X	2000
#define T	1000
#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], yy[N], uu[N], vv[N]; int 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 solve2() {
	static int dd[X * 2 + 1][X * 2 + 1], nn[T + 1];
	int h, i, x, y;

	for (x = 0; x <= X * 2; x++)
		for (y = 0; y <= X * 2; y++)
			dd[x][y] = T + 1;
	for (i = 0; i < n; i++)
		dd[X + xx[i]][X + yy[i]] = 0;
	for (x = 0; x <= X * 2; x++) {
		for (y = 1; y <= X * 2; y++)
			dd[x][y] = min(dd[x][y], dd[x][y - 1] + 1);
		for (y = X * 2 - 1; y >= 0; y--)
			dd[x][y] = min(dd[x][y], dd[x][y + 1] + 1);
	}
	for (y = 0; y <= X * 2; y++) {
		for (x = 1; x <= X * 2; x++)
			dd[x][y] = min(dd[x][y], dd[x - 1][y] + 1);
		for (x = X * 2 - 1; x >= 0; x--)
			dd[x][y] = min(dd[x][y], dd[x + 1][y] + 1);
	}
	memset(nn, 0, (T + 1) * sizeof *nn);
	for (x = 0; x <= X * 2; x++)
		for (y = 0; y <= X * 2; y++)
			if (dd[x][y] <= T)
				nn[dd[x][y]]++;
	for (h = 0; h < q; h++)
		ans[h] = nn[tt[h]];
}

void solve4() {
	static int ii[N];
	int h, i, i_, a, t;
	long long b;

	for (i = 0; i < n; i++)
		ii[i] = i;
	ww = xx, sort(ii, 0, n);
	for (i = 0; i + 1 < n; i++) {
		tt_[i] = xx[ii[i + 1]] - xx[ii[i]];
		ii[i] = i;
	}
	ww = tt_, sort(ii, 0, n - 1);
	i = 0, a = n * 4, b = 0;
	for (h = 0; h < q; h++) {
		t = tt[h];
		if (t == 0) {
			ans[h] = n;
			continue;
		}
		while (i < n - 1 && tt_[i_ = ii[i]] < t) {
			a -= 4, b += tt_[i_] * 2;
			i++;
		}
		ans[h] = 0;
		while (i < n - 1 && tt_[i_ = ii[i]] == t) {
			ans[h] += t - 1;
			a -= 4, b += tt_[i_] * 2;
			i++;
		}
		ans[h] += (long long) a * t + b;
	}
}

int xx_[N], yy_[N];

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 *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 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 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;
}

void solve6() {
	static int ii[N], qu[N], jjl[N * 4], jjr[N * 4];
	int cnt, h, i, i_, j, j_, jl, jr, r, o, t, t_, tmp;
	long long u, u_, ul, ur;

	for (i = 0; i < n; i++)
		uu[i] = xx[i] - yy[i], vv[i] = xx[i] + yy[i];
	memset(aa, 0, (q + 1) * sizeof *aa), memset(bb, 0, (q + 1) * sizeof *bb);
	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]);
	}
	cnt = 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;
			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)
					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;
					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;
					else {
						ur = min(ur, u_);
						if (uu[jr] > uu[j] || uu[jr] == uu[j] && jr > j)
							jr = j;
					}
				}
			}
			if (jl != -1 && jr != -1)
				jjl[cnt] = jl, jjr[cnt] = jr, cnt++;
		}
		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 < cnt; h++) {
		jl = jjl[h], jr = jjr[h];
		append(jl, jr), append(jr, jl);
	}
	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];
}

void test() {
	static long long ans_[Q];
	int h;

	solve2(), memcpy(ans_, ans, q * sizeof *ans), solve6();
	for (h = 0; h < q; h++)
		if (ans[h] != ans_[h]) {
			printf("wrong answer on query %d: expected %lld, found %lld\n", h + 1, ans_[h], ans[h]);
			exit(0);
		}
}

void stress() {
	int t, h, i, j;

	for (t = 1; t <= T; t++) {
		printf("running on test %d...\n", t);
generate:
		n = 10, q = T + 1;
		for (i = 0; i < n; i++)
			xx[i] = rand_() % 21 - 10, yy[i] = rand_() % 21 - 10;
		for (i = 0; i < n; i++)
			for (j = i + 1; j < n; j++)
				if (xx[j] == xx[i] && yy[j] == yy[i])
					goto generate;
		for (h = 0; h < q; h++)
			tt[h] = h;
		test();
	}
	printf("AC\n");
}

int main() {
	int h, i;

	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]);
#if 0
	stress();
	return 0;
#endif
	solve6();
	for (h = 0; h < q; h++)
		printf("%lld\n", ans[h]);
	return 0;
}

Compilation message

cell.c: In function 'append':
cell.c:130:23: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
  130 |  if (o >= 2 && (o & o - 1) == 0)
      |                     ~~^~~
cell.c: In function 'min_':
cell.c:138:64: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  138 |  return j == -1 || i != -1 && (vv[i] < vv[j] || vv[i] == vv[j] && i < j) ? i : j;
      |                                                 ~~~~~~~~~~~~~~~^~~~~~~~
cell.c:138:28: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  138 |  return j == -1 || i != -1 && (vv[i] < vv[j] || vv[i] == vv[j] && i < j) ? i : j;
      |                    ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cell.c: In function 'solve6':
cell.c:243:41: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  243 |     if (vv[j] < vv[i] || vv[j] == vv[i] && j > i)
      |                          ~~~~~~~~~~~~~~~^~~~~~~~
cell.c:254:45: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  254 |       if (uu[jl] < uu[j] || uu[jl] == uu[j] && jl > j)
      |                             ~~~~~~~~~~~~~~~~^~~~~~~~~
cell.c:263:45: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  263 |       if (uu[jr] > uu[j] || uu[jr] == uu[j] && jr > j)
      |                             ~~~~~~~~~~~~~~~~^~~~~~~~~
cell.c:297:41: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  297 |     if (vv[j] < vv[i] || vv[j] == vv[i] && j > i)
      |                          ~~~~~~~~~~~~~~~^~~~~~~~
cell.c: In function 'main':
cell.c:368:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  368 |  scanf("%d%d", &n, &q);
      |  ^~~~~~~~~~~~~~~~~~~~~
cell.c:370:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  370 |   scanf("%d%d", &xx[i], &yy[i]);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cell.c:372:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  372 |   scanf("%d", &tt[h]);
      |   ^~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 20824 KB Output is correct
2 Correct 3 ms 20828 KB Output is correct
3 Correct 3 ms 20828 KB Output is correct
4 Correct 3 ms 20828 KB Output is correct
5 Correct 3 ms 20828 KB Output is correct
6 Correct 3 ms 20828 KB Output is correct
7 Correct 2 ms 20824 KB Output is correct
8 Correct 43 ms 22868 KB Output is correct
9 Correct 2 ms 20828 KB Output is correct
10 Correct 3 ms 20828 KB Output is correct
11 Correct 2 ms 20828 KB Output is correct
12 Correct 7 ms 21084 KB Output is correct
13 Correct 7 ms 20952 KB Output is correct
14 Incorrect 8 ms 21084 KB Output isn't correct
15 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 2 ms 20824 KB Output is correct
2 Correct 3 ms 20828 KB Output is correct
3 Correct 3 ms 20828 KB Output is correct
4 Correct 3 ms 20828 KB Output is correct
5 Correct 3 ms 20828 KB Output is correct
6 Correct 3 ms 20828 KB Output is correct
7 Correct 2 ms 20824 KB Output is correct
8 Correct 43 ms 22868 KB Output is correct
9 Correct 2 ms 20828 KB Output is correct
10 Correct 3 ms 20828 KB Output is correct
11 Correct 2 ms 20828 KB Output is correct
12 Correct 7 ms 21084 KB Output is correct
13 Correct 7 ms 20952 KB Output is correct
14 Incorrect 8 ms 21084 KB Output isn't correct
15 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 235 ms 27732 KB Output is correct
2 Correct 221 ms 27616 KB Output is correct
3 Correct 234 ms 27628 KB Output is correct
4 Correct 232 ms 27740 KB Output is correct
5 Correct 261 ms 27732 KB Output is correct
6 Correct 209 ms 27616 KB Output is correct
7 Correct 238 ms 27728 KB Output is correct
8 Correct 2 ms 18780 KB Output is correct
9 Correct 2 ms 18776 KB Output is correct
10 Correct 4 ms 20828 KB Output is correct
11 Correct 240 ms 27556 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 235 ms 27732 KB Output is correct
2 Correct 221 ms 27616 KB Output is correct
3 Correct 234 ms 27628 KB Output is correct
4 Correct 232 ms 27740 KB Output is correct
5 Correct 261 ms 27732 KB Output is correct
6 Correct 209 ms 27616 KB Output is correct
7 Correct 238 ms 27728 KB Output is correct
8 Correct 2 ms 18780 KB Output is correct
9 Correct 2 ms 18776 KB Output is correct
10 Correct 4 ms 20828 KB Output is correct
11 Correct 240 ms 27556 KB Output is correct
12 Correct 500 ms 38300 KB Output is correct
13 Correct 433 ms 38500 KB Output is correct
14 Correct 404 ms 38292 KB Output is correct
15 Correct 402 ms 38488 KB Output is correct
16 Correct 78 ms 27732 KB Output is correct
17 Correct 78 ms 27796 KB Output is correct
18 Correct 82 ms 31652 KB Output is correct
19 Correct 384 ms 38484 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 7 ms 21080 KB Output is correct
2 Correct 7 ms 21084 KB Output is correct
3 Correct 11 ms 21324 KB Output is correct
4 Correct 10 ms 21084 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 7 ms 21080 KB Output is correct
2 Correct 7 ms 21084 KB Output is correct
3 Correct 11 ms 21324 KB Output is correct
4 Correct 10 ms 21084 KB Output is correct
5 Correct 84 ms 31356 KB Output is correct
6 Correct 101 ms 31704 KB Output is correct
7 Correct 86 ms 31912 KB Output is correct
8 Correct 87 ms 31976 KB Output is correct
9 Correct 93 ms 31840 KB Output is correct
10 Correct 87 ms 31908 KB Output is correct
11 Correct 89 ms 32340 KB Output is correct
12 Correct 107 ms 32160 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 20824 KB Output is correct
2 Correct 3 ms 20828 KB Output is correct
3 Correct 3 ms 20828 KB Output is correct
4 Correct 3 ms 20828 KB Output is correct
5 Correct 3 ms 20828 KB Output is correct
6 Correct 3 ms 20828 KB Output is correct
7 Correct 2 ms 20824 KB Output is correct
8 Correct 43 ms 22868 KB Output is correct
9 Correct 2 ms 20828 KB Output is correct
10 Correct 3 ms 20828 KB Output is correct
11 Correct 2 ms 20828 KB Output is correct
12 Correct 7 ms 21084 KB Output is correct
13 Correct 7 ms 20952 KB Output is correct
14 Incorrect 8 ms 21084 KB Output isn't correct
15 Halted 0 ms 0 KB -