Submission #1125290

#TimeUsernameProblemLanguageResultExecution timeMemory
1125290sleepntsheepRoad Construction (JOI21_road_construction)C11
0 / 100
5031 ms85792 KiB
#include <stdio.h> #define N 250000 #define M (250000 * 30) int n, k, x[N], y[N], /* inputs */ x2[N], y2[N], /* x[] and y[] seperatedly sorted */ x3[N], y3[N], /* x2[x3[i]] = x[i] */ ii[N], /* indices sorted by x */ ii2[N], /* indices sorted by y */ rt[N], L[M], R[M], jj, ee[N * 2], eo; long long A[M]; /* persistent segment tree */ void csort(int *a, int n, int offset) { #define B 45000 int i; static int count[B], pass_1[N]; for (i = 0; i < B; ++i) count[i] = 0; for (i = 0; i < n; ++i) { a[i] += offset; ++count[a[i] % B]; } for (i = B - 2; i >= 0; --i) count[i] += count[i + 1]; for (i = 0; i < n; ++i) pass_1[--count[a[i] % B]] = a[i]; for (i = 0; i < B; ++i) count[i] = 0; for (i = 0; i < n; ++i) ++count[pass_1[i] / B]; for (i = 1; i < B; ++i) count[i] += count[i - 1]; for (i = 0; i < n; ++i) a[--count[pass_1[i] / B]] = pass_1[i] - offset; #undef B } int lower_bound(int *a, int n, long long x) { int lower, upper; lower = -1; upper = n; while (upper - lower > 1) { int mid; mid = lower + (upper - lower) / 2; if (a[mid] >= x) upper = mid; else lower = mid; } return upper; } int prev_upper_bound(int *a, int n, int x) { int lower, upper; lower = -1; upper = n; while (upper - lower > 1) { int mid; mid = lower + (upper - lower) / 2; if (a[mid] <= x) lower = mid; else upper = mid; } return lower; } int persist_new0(int val) { int i; i = ++jj; A[i] = val; L[i] = R[i] = 0; return i; } int persist_new1(int lc, int rc) { int i; i = ++jj; A[i] = A[lc] + A[rc]; L[i] = lc; R[i] = rc; return i; } int persist_add(int v, int l, int r, int p, int k) { if (l == r) return persist_new0(A[v] + k); if (p <= (l + r) / 2) return persist_new1(persist_add(L[v], l, (l + r) / 2, p, k), R[v]); return persist_new1(L[v], persist_add(R[v], (l + r) / 2 + 1, r, p, k)); } long long persist_sum(int v, int l, int r, int x, int y) { if (r < x || y < l) return 0; if (x <= l && r <= y) return A[v]; return persist_sum(L[v], l, (l + r) / 2, x, y) + persist_sum(R[v], (l + r) / 2 + 1, r, x, y); } long long count(long long v) { long long z; int i, p_left, p_right; jj = 0; rt[0] = 0; for (i = 0; i < n; ++i) { rt[i + 1] = rt[i]; rt[i + 1] = persist_add(rt[i + 1], 0, n, y3[ii[i]], 1); } z = 0; p_left = 0; p_right = 0; for (i = 0; i < n; ++i) { int y_1, y_2; while (p_right + 1 < n && x[ii[p_right + 1]] <= v + x[ii[i]]) ++p_right; while (p_left < i && x[ii[p_left]] + v < x[ii[i]]) ++p_left; y_1 = lower_bound(y2, n, y[ii[i]] - v); y_2 = prev_upper_bound(y2, n, y[ii[i]] + v); --z; z += persist_sum(rt[p_right + 1], 0, n, y_1, y_2) - persist_sum(rt[p_left], 0, n, y_1, y_2); } return z / 2; } void input() { int i, xx, yy; scanf("%d%d", &n, &k); for (i = 0; i < n; ++i) { scanf("%d%d", &xx, &yy); x[i] = xx + yy; y[i] = xx - yy; x2[i] = x[i]; y2[i] = y[i]; } } void prepare() { static int freq[N], ptr[N]; int i, run; csort(x2, n, 1e9); csort(y2, n, 1e9); for (i = 0; i < n; ++i) { x3[i] = lower_bound(x2, n, x[i]); y3[i] = lower_bound(y2, n, y[i]); ++freq[x3[i]]; } run = 0; for (i = 0; i < n; ++i) { ptr[i] = run; run += freq[i]; } for (i = 0; i < n; ++i) ii[ptr[x3[i]]++] = i; for (i = 0; i < n; ++i) { ptr[i] = 0; freq[i] = 0; } for (i = 0; i < n; ++i) ++freq[y3[i]]; run = 0; for (i = 0; i < n; ++i) { ptr[i] = run; run += freq[i]; } } unsigned kth() { unsigned lower, upper; lower = 0; upper = 4e9 + 1; while (upper - lower > 1) { unsigned mid; mid = lower + (upper - lower) / 2; if (count(mid) >= k) upper = mid; else lower = mid; } return upper; } long long abs_(long long x) { return x < 0 ? -x : x; } long long max(long long a, long long b) { return a > b ? a : b; } long long distance(int i, int j) { return max(abs_(x[i] * 1ll - x[j]), abs_(y[i] * 1ll - y[j])); } void make_edge(int i, int j, long long threshold) { long long dd = distance(i, j); if (eo > 250000) return; if (persist_sum(rt[i], 0, n, j, j)) return; if (dd > threshold) return; rt[i] = persist_add(rt[i], 0, n, j, 1); ee[eo++] = distance(i, j); if (ee[eo - 1] > 2e9) __builtin_trap(); } void fetch_not_exceeding(long long d) { int i, j, k; j = 0; for (i = 0; i < n; ++i) { while (j < n && x[ii[j]] <= x[ii[i]] + d) ++j; for (k = i + 1; k < j; ++k) make_edge(i, k, d); } j = 0; for (i = 0; i < n; ++i) { while (j < n && y[ii[j]] <= y[ii[i]] + d) ++j; for (k = i + 1; k < j; ++k) make_edge(i, k, d); } } void answer() { unsigned last; int i; last = kth(); jj = 0; for (i = 0; i < n; ++i) rt[i] = 0; if (last == 0) __builtin_trap(); fetch_not_exceeding(last - 1); fetch_not_exceeding(last); csort(ee, eo, 0); for (i = 0; i < k; ++i) printf("%d\n", ee[i]); } void debug() { int i; return; printf("x2[] : "); for (i = 0; i < n; ++i) printf(" %d", x2[i]); puts(""); printf("y2[] : "); for (i = 0; i < n; ++i) printf(" %d", y2[i]); puts(""); printf("x3[] : "); for (i = 0; i < n; ++i) printf(" %d", x3[i]); puts(""); printf("y3[] : "); for (i = 0; i < n; ++i) printf(" %d", y3[i]); puts(""); printf("ii[] : "); for (i = 0; i < n; ++i) printf(" %d", ii[i]); puts(""); printf("count(1) = %lld\n",count(1)); printf("count(10) = %lld\n",count(10)); } int main() { input(); prepare(); debug(); answer(); return 0; }

Compilation message (stderr)

road_construction.c: In function 'input':
road_construction.c:166:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  166 |   scanf("%d%d", &n, &k);
      |   ^~~~~~~~~~~~~~~~~~~~~
road_construction.c:169:5: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  169 |     scanf("%d%d", &xx, &yy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~
#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...