제출 #768851

#제출 시각아이디문제언어결과실행 시간메모리
768851rainboySegments (IZhO18_segments)C11
31 / 100
1073 ms5852 KiB
#include <stdio.h>

#define N	200000
#define K	2000
#define M	((N + K - 1) / K)

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

unsigned int X = 12345;

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

int ll[N], rr[N], ss[N], n;

int compare_l(int i, int j) { return ll[i] - ll[j]; }
int compare_r(int i, int j) { return rr[i] - rr[j]; }

int ii1[M], iii[M][K * 2], iiil[M][K * 2], iiir[M][K * 2], kk[M];

int (*compare)(int, int);

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 = compare(ii[j], i_);

			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 build() {
	static int ii_[N];
	int n_, g, h, l, r;

	n_ = 0;
	for (g = 0; g < M; g++)
		for (h = 0; h < kk[g]; h++)
			ii_[n_++] = iii[g][h];
	for (g = 0; g < M; g++) {
		l = min(g * K, n_), r = min((g + 1) * K, n_), kk[g] = r - l;
		for (h = 0; h < kk[g]; h++)
			iii[g][h] = iiil[g][h] = iiir[g][h] = ii_[l + h];
		ii1[g] = kk[g] == 0 ? -1 : ii_[l];
		compare = compare_l, sort(iiil[g], 0, kk[g]);
		compare = compare_r, sort(iiir[g], 0, kk[g]);
	}
}

void add(int l, int r) {
	int g, h, i;

	i = n++;
	ll[i] = l, rr[i] = r, ss[i] = r - l + 1;
	for (g = 1; g < M; g++)
		if (ii1[g] == -1 || ss[i] < ss[ii1[g]])
			break;
	g--;
	for (h = kk[g]; h > 0 && ss[i] < ss[iii[g][h - 1]]; h--)
		iii[g][h] = iii[g][h - 1];
	iii[g][h] = i;
	for (h = kk[g]; h > 0 && ll[i] < ll[iiil[g][h - 1]]; h--)
		iiil[g][h] = iiil[g][h - 1];
	iiil[g][h] = i;
	for (h = kk[g]; h > 0 && rr[i] < rr[iiir[g][h - 1]]; h--)
		iiir[g][h] = iiir[g][h - 1];
	iiir[g][h] = i;
	kk[g]++;
}

void remove_(int i) {
	int g, h;

	for (g = 1; g < M; g++)
		if (ii1[g] == -1 || ss[i] < ss[ii1[g]] || ss[i] == ss[ii1[g]] && i < ii1[g])
			break;
	g--;
	for (h = 0; h < kk[g]; h++)
		if (iii[g][h] == i) {
			while (h + 1 < kk[g])
				iii[g][h] = iii[g][h + 1], h++;
			break;
		}
	for (h = 0; h < kk[g]; h++)
		if (iiil[g][h] == i) {
			while (h + 1 < kk[g])
				iiil[g][h] = iiil[g][h + 1], h++;
			break;
		}
	for (h = 0; h < kk[g]; h++)
		if (iiir[g][h] == i) {
			while (h + 1 < kk[g])
				iiir[g][h] = iiir[g][h + 1], h++;
			break;
		}
	kk[g]--;
}

int query(int l, int r, int s) {
	int g, h, i, cnt, lower, upper;

	if (r - l + 1 < s)
		return 0;
	cnt = 0;
	for (g = M - 1; g >= 0; g--)
		if (ii1[g] == -1 || ss[ii1[g]] >= s) {
			cnt += kk[g];
			lower = -1, upper = kk[g];
			while (upper - lower > 1) {
				h = (lower + upper) / 2;
				if (r - ll[iiil[g][h]] + 1 >= s)
					lower = h;
				else
					upper = h;
			}
			cnt -= kk[g] - upper;
			lower = -1, upper = kk[g];
			while (upper - lower > 1) {
				h = (lower + upper) / 2;
				if (rr[iiir[g][h]] - l + 1 >= s)
					upper = h;
				else
					lower = h;
			}
			cnt -= upper;
		} else {
			for (h = 0; h < kk[g]; h++) {
				i = iii[g][h];
				if (min(rr[i], r) - max(ll[i], l) + 1 >= s)
					cnt++;
			}
			break;
		}
	return cnt;
}

int main() {
	int q, online, h, i, ans;

	scanf("%d%d", &q, &online);
	ans = 0;
	for (h = 0; h < q; h++) {
		int t, l, r, s, tmp;

		if (h % K == 0)
			build();
		scanf("%d", &t);
		if (t == 1) {
			scanf("%d%d", &l, &r);
			if (online)
				l ^= ans, r ^= ans;
			if (l > r)
				tmp = l, l = r, r = tmp;
			add(l, r);
		} else if (t == 2) {
			scanf("%d", &i), i--;
			remove_(i);
		} else {
			scanf("%d%d%d", &l, &r, &s);
			if (online)
				l ^= ans, r ^= ans;
			if (l > r)
				tmp = l, l = r, r = tmp;
			printf("%d\n", ans = query(l, r, s));
		}
	}
	return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

segments.c: In function 'remove_':
segments.c:90:65: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   90 |   if (ii1[g] == -1 || ss[i] < ss[ii1[g]] || ss[i] == ss[ii1[g]] && i < ii1[g])
      |                                             ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
segments.c: In function 'main':
segments.c:155:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  155 |  scanf("%d%d", &q, &online);
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~
segments.c:162:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  162 |   scanf("%d", &t);
      |   ^~~~~~~~~~~~~~~
segments.c:164:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  164 |    scanf("%d%d", &l, &r);
      |    ^~~~~~~~~~~~~~~~~~~~~
segments.c:171:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  171 |    scanf("%d", &i), i--;
      |    ^~~~~~~~~~~~~~~
segments.c:174:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
  174 |    scanf("%d%d%d", &l, &r, &s);
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...