답안 #485922

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
485922 2021-11-09T18:42:02 Z rainboy OGLEDALA (COI15_ogledala) C
100 / 100
1631 ms 139012 KB
#include <stdio.h>

#define N	100000
#define K	100
#define M	(N * K)

unsigned int X = 12345;

int rand_() {
	return (X *= 3) >> 1;
}

long long dd[M], kk[M]; int ii[M];

void sort(int *hh, int l, int r) {
	while (l < r) {
		int i = l, j = l, k = r, h = hh[l + rand_() % (r - l)], tmp;

		while (j < k) {
			int c = dd[hh[j]] != dd[h] ? (dd[hh[j]] > dd[h] ? -1 : 1) : hh[j] - h;

			if (c == 0)
				j++;
			else if (c < 0) {
				tmp = hh[i], hh[i] = hh[j], hh[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = hh[j], hh[j] = hh[k], hh[k] = tmp;
			}
		}
		sort(hh, l, i);
		l = k;
	}
}

long long count(long long a, long long b) {
	long long k, l, k_, l_;

	k = 1, l = 0;
	while (a > 2) {
		if (b == a)
			return k;
		if (b == a - 1)
			return a == 3 ? k + l : l;
		if (a % 2 == 0)
			k_ = k * 2 + l, l_ = l;
		else
			k_ = k, l_ = k + l * 2;
		a = (a + 1) / 2, k = k_, l = l_;
	}
	return b == a ? k : 0;
}

long long idx(long long a, long long b, long long k) {
	long long c;

	if (a == b)
		return 0;
	c = count(a / 2, b);
	return k <= c ? idx(a / 2, b, k) : a / 2 + idx((a + 1) / 2, b, k - c);
}

int main() {
	static int hh[M];
	static long long aa[N + 2];
	long long x, k_;
	int n, m, q, h, i;

	scanf("%lld%d%d", &x, &n, &q);
	m = 0;
	for (i = 1; i <= n + 1; i++) {
		long long d, k, k_, l, l_;

		if (i <= n)
			scanf("%lld", &aa[i]);
		else
			aa[i] = x + 1;
		d = aa[i] - aa[i - 1];
		if (d == 1)
			continue;
		if (d == 2) {
			dd[m] = 2, kk[m] = 1, ii[m] = i, m++;
			continue;
		}
		k = 1, l = 0;
		while (d > 2) {
			if (d % 2 == 0)
				k_ = k * 2 + l, l_ = l;
			else
				k_ = k, l_ = k + l * 2;
			if (k > 0)
				dd[m] = d, kk[m] = k, ii[m] = i, m++;
			if (l > 0)
				dd[m] = d - 1, kk[m] = l, ii[m] = i, m++;
			d = (d + 1) / 2, k = k_, l = l_;
		}
		if (d == 2 && k > 0) {
			if (dd[m - 1] != d)
				dd[m] = d, kk[m] = k, ii[m] = i, m++;
			else
				kk[m - 1] += k;
		}
	}
	for (h = 0; h < m; h++)
		hh[h] = h;
	sort(hh, 0, m);
	h = 0, k_ = n;
	while (q--) {
		long long k;

		scanf("%lld", &k);
		if (k <= n)
			printf("%lld\n", aa[k]);
		else {
			while (h < m && k_ + kk[hh[h]] < k)
				k_ += kk[hh[h++]];
			i = ii[hh[h]];
			printf("%lld\n", aa[i - 1] + idx(aa[i] - aa[i - 1], dd[hh[h]], k - k_) + dd[hh[h]] / 2);
		}
	}
	return 0;
}

Compilation message

ogledala.c: In function 'main':
ogledala.c:70:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
   70 |  scanf("%lld%d%d", &x, &n, &q);
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ogledala.c:76:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
   76 |    scanf("%lld", &aa[i]);
      |    ^~~~~~~~~~~~~~~~~~~~~
ogledala.c:112:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  112 |   scanf("%lld", &k);
      |   ^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 25 ms 1656 KB Output is correct
4 Correct 34 ms 1764 KB Output is correct
5 Correct 62 ms 4964 KB Output is correct
6 Correct 53 ms 5572 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 460 KB Output is correct
2 Correct 3 ms 460 KB Output is correct
3 Correct 1190 ms 117156 KB Output is correct
4 Correct 1251 ms 120340 KB Output is correct
5 Correct 1375 ms 132920 KB Output is correct
6 Correct 1405 ms 136040 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 781 ms 70964 KB Output is correct
2 Correct 873 ms 75456 KB Output is correct
3 Correct 1182 ms 104068 KB Output is correct
4 Correct 1290 ms 107204 KB Output is correct
5 Correct 1564 ms 135844 KB Output is correct
6 Correct 1631 ms 139012 KB Output is correct