이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 (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;
}
컴파일 시 표준 에러 (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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |