Submission #768857

#TimeUsernameProblemLanguageResultExecution timeMemory
768857rainboySegments (IZhO18_segments)C11
100 / 100
3422 ms6328 KiB
#include <stdio.h>
 
#define N	200000
#define K	3000
#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 (g > 0 && (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;
}

Compilation message (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...