이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100000
#define N_ (1 << 17) /* N_ = pow2(ceil(log2(N))) */
unsigned int X = 12345;
int rand_() {
return (X *= 3) >> 1;
}
int min(int a, int b) { return a < b ? a : b; }
int *oj[N], oo[N];
void append(int i, int j) {
int o = oo[i]++;
if (o >= 2 && (o & o - 1) == 0)
oj[i] = (int *) realloc(oj[i], o * 2 * sizeof *oj[i]);
oj[i][o] = j;
}
int pp[N], qq[N], dd[N], sz[N], jj[N], dp[N], qu[N], cnt;
void dfs1(int i, int d) {
int o, j_;
qu[cnt++] = i;
j_ = -1;
dd[i] = d, sz[i] = 1, dp[i] = i;
for (o = 0; o < oo[i]; o++) {
int j = oj[i][o];
dfs1(j, d + 1);
if (j_ == -1 || sz[j_] < sz[j])
j_ = j;
sz[i] += sz[j];
dp[i] = min(dp[i], dp[j]);
}
jj[i] = j_;
if (j_ != -1)
qq[j_] = -1;
}
int lca_(int i, int j) {
int i_ = i, a;
while (qq[i] != qq[j])
if (dd[qq[i]] > dd[qq[j]])
i = pp[qq[i]];
else
j = pp[qq[j]];
a = dd[i] < dd[j] ? i : j;
i = qq[i_];
while (dd[i] > dd[a] + 1)
i = qq[pp[i]];
return dd[i] == dd[a] + 1 ? i : jj[a];
}
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)
if (dp[ii[j]] == dp[i_])
j++;
else if (dp[ii[j]] < dp[i_]) {
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;
}
}
int hh[N];
void dfs2(int i) {
int o;
sort(oj[i], 0, oo[i]);
for (o = 0; o < oo[i]; o++) {
int j = oj[i][o];
dfs2(j);
}
hh[qu[cnt] = i] = cnt, cnt++;
}
int st[N_ * 2], h_, n_; char lz[N_];
void put(int i) {
st[i] = 0;
if (i < n_)
lz[i] = 1;
}
void pus(int i) {
if (lz[i]) {
put(i << 1), put(i << 1 | 1);
lz[i] = 0;
}
}
void pul(int i) {
if (!lz[i])
st[i] = st[i << 1] + st[i << 1 | 1];
}
void push(int i) {
int h;
for (h = h_; h > 0; h--)
pus(i >> h);
}
void pull(int i) {
while (i > 1)
pul(i >>= 1);
}
void build(int n) {
int i;
h_ = 0;
while (1 << h_ < n)
h_++;
n_ = 1 << h_;
for (i = 0; i < n; i++)
st[n_ + i] = 1;
for (i = n_ - 1; i > 0; i--)
pul(i);
}
int find(int k) {
int i = 1;
while (i < n_) {
pus(i);
i <<= 1;
if (k > st[i])
k -= st[i], i ^= 1;
}
return i - n_;
}
void update(int r) {
int l = 0, l_ = l += n_, r_ = r += n_;
push(l_), push(r_);
for ( ; l <= r; l >>= 1, r >>= 1) {
if ((l & 1) == 1)
put(l++);
if ((r & 1) == 0)
put(r--);
}
pull(l_), pull(r_);
}
void upd(int i) {
push(i += n_);
st[i] = 1;
pull(i);
}
int higher(int l) {
int r = n_ - 1, l_ = l += n_, r_ = r += n_;
push(l_), push(r_);
for ( ; l <= r; l >>= 1, r >>= 1)
if ((l & 1) == 1) {
if (st[l] > 0) {
while (l < n_) {
pus(l);
l = st[l << 1] > 0 ? l << 1 : l << 1 | 1;
}
return l - n_;
}
l++;
}
return -1;
}
int main() {
int n, q, h, i, r;
scanf("%d%d", &n, &q);
r = -1;
for (i = 0; i < n; i++)
oj[i] = (int *) malloc(2 * sizeof *oj[i]);
for (i = 0; i < n; i++) {
scanf("%d", &pp[i]), pp[i]--;
if (pp[i] == -1)
r = i;
else
append(pp[i], i);
}
dfs1(r, 0);
for (h = 0; h < cnt; h++) {
i = qu[h];
qq[i] = qq[i] ? qq[pp[i]] : i;
}
cnt = 0;
dfs2(r);
build(n);
while (q--) {
int t;
scanf("%d", &t);
if (t == 1) {
int k;
scanf("%d", &k);
h = find(k);
update(h);
printf("%d\n", qu[h] + 1);
} else {
int p;
scanf("%d", &i), i--;
h = higher(hh[i]);
p = h == -1 ? r : lca_(i, qu[h]);
upd(hh[p]);
printf("%d\n", dd[i] - dd[p]);
}
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
ballmachine.c: In function 'append':
ballmachine.c:21:23: warning: suggest parentheses around '-' in operand of '&' [-Wparentheses]
21 | if (o >= 2 && (o & o - 1) == 0)
| ~~^~~
ballmachine.c: In function 'main':
ballmachine.c:193:2: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
193 | scanf("%d%d", &n, &q);
| ^~~~~~~~~~~~~~~~~~~~~
ballmachine.c:198:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
198 | scanf("%d", &pp[i]), pp[i]--;
| ^~~~~~~~~~~~~~~~~~~
ballmachine.c:215:3: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
215 | scanf("%d", &t);
| ^~~~~~~~~~~~~~~
ballmachine.c:219:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
219 | scanf("%d", &k);
| ^~~~~~~~~~~~~~~
ballmachine.c:226:4: warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result' [-Wunused-result]
226 | scanf("%d", &i), i--;
| ^~~~~~~~~~~~~~~
# | 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... |