Submission #71105109
Source Code Expand
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <stdio.h>
#include <stdlib.h>
int N, M;
int x[114514], y[114514];
int add(int a, int b) {
return a + b - M * (a + b >= M);
}
int mul(int a, int b) {
return (int)((long long)a * b % M);
}
int ec[114514], *es[114514];
void ae(int f, int t) {
es[f] = realloc(es[f], sizeof(*es[f]) * (ec[f] + 1));
if (es[f] == NULL) exit(2);
es[f][ec[f]++] = t;
}
int cmp(const void* x, const void* y) {
int a = *(const int*)x, b = *(const int*)y;
return (a > b) - (a < b);
}
/* 点set、範囲mulのセグメント木 */
#define KI_MAX (1 << 17) /* 131072 */
struct ki_s {
int value;
struct ki_s *next[2];
};
int ki_set_i(struct ki_s** pki, int ss, int se, int query, int value) {
if (query < ss || se <= query) { /* 完全に外れている */
return *pki == NULL ? 1 : (*pki)->value;
}
if (*pki == NULL) {
*pki = malloc(sizeof(**pki));
if (*pki == NULL) exit(2);
**pki = (struct ki_s){ 1, { NULL, NULL } };
}
if (ss == query && se == query + 1) { /* セグメントがクエリに完全に含まれる */
(*pki)->value = value;
} else {
int sm = ss + (se - ss) / 2;
(*pki)->value = mul(
ki_set_i(&(*pki)->next[0], ss, sm, query, value),
ki_set_i(&(*pki)->next[1], sm, se, query, value)
);
}
return (*pki)->value;
}
void ki_set(struct ki_s** pki, int query, int value) {
ki_set_i(pki, 0, KI_MAX, query, value);
}
int ki_get_i(const struct ki_s* ki, int ss, int se, int qs, int qe) {
if (ki == NULL) return 1; /* ここは全て初期値 */
if (qe <= ss || se <= qs) { /* 完全に外れている */
return 1;
} else if (qs <= ss && se <= qe) { /* セグメントがクエリに完全に含まれる */
return ki->value;
} else {
int sm = ss + (se - ss) / 2;
return mul(
ki_get_i(ki->next[0], ss, sm, qs, qe),
ki_get_i(ki->next[1], sm, se, qs, qe)
);
}
}
int ki_get(const struct ki_s* ki, int qs, int qe) {
return ki_get_i(ki, 0, KI_MAX, qs, qe);
}
/* 0:未探索、1~ec[node]:その番目(1-origin)の子だけ未探索、-1:探索済 */
int status[114514];
struct ki_s* children_info[114514];
int* memo[114514];
int get_idx(const int* array, int array_size, int target) {
int l = 0, r = array_size - 1;
while (l <= r) {
int m = l + (r - l) / 2;
if (array[m] == target) return m;
else if (array[m] < target) l = m + 1;
else r = m - 1;
}
return array_size;
}
int calc(int node, int parent) {
int parent_id = get_idx(es[node], ec[node], parent);
int ans;
if (memo[node][parent_id]) return ~memo[node][parent_id];
if (status[node] == 0) {
int i;
for (i = 0; i < ec[node]; i++) {
if (es[node][i] != parent) ki_set(&children_info[node], i, add(calc(es[node][i], node), 1));
}
status[node] = parent_id >= ec[node] ? -1 : parent_id + 1;
} else if (status[node] > 0) {
/* 抜けたのと同じ頂点が親のときは、memo が使えるので、ここには来ないはず */
ki_set(&children_info[node], status[node] - 1, add(calc(es[node][status[node] - 1], node), 1));
status[node] = -1;
}
if (parent_id >= ec[node]) {
ans = ki_get(children_info[node], 0, ec[node]);
} else {
ans = mul(
ki_get(children_info[node], 0, parent_id),
ki_get(children_info[node], parent_id + 1, ec[node])
);
}
return ~(memo[node][parent_id] = ~ans);
}
int main(void) {
int i;
if (scanf("%d%d", &N, &M) != 2) return 1;
for (i = 1; i < N; i++) {
if (scanf("%d%d", &x[i], &y[i]) != 2) return 1;
ae(x[i], y[i]);
ae(y[i], x[i]);
}
for (i = 1; i <= N; i++) {
if (ec[i] > 0) qsort(es[i], ec[i], sizeof(*es[i]), cmp);
memo[i] = calloc(ec[i] + 1, sizeof(*memo[i]));
if (memo[i] == NULL) return 2;
}
for (i = 1; i <= N; i++) printf("%d\n", calc(i, 0));
return 0;
}
/*
木 → 迂回路とかは無い
黒い頂点のみを辿って到達できる → 黒い頂点は連結
頂点 v が黒である → そこを根として、どこまで黒を伸ばすか?
ある頂点が黒のとき、それぞれの子について
* 黒にしない → 1通り
* 黒にする → 再帰
これらの和を、全ての子について掛ける
*/
Submission Info
| Submission Time |
|
| Task |
V - Subtree |
| User |
mikecat |
| Language |
C (gcc 12.2.0) |
| Score |
100 |
| Code Size |
4207 Byte |
| Status |
AC |
| Exec Time |
247 ms |
| Memory |
77176 KiB |
Judge Result
| Set Name |
All |
| Score / Max Score |
100 / 100 |
| Status |
|
| Set Name |
Test Cases |
| All |
0_00, 0_01, 0_02, 0_03, 1_00, 1_01, 1_02, 1_03, 1_04, 1_05, 1_06, 1_07, 1_08, 1_09, 1_10, 1_11, 1_12, 1_13, 1_14, 1_15, 1_16, 1_17, 1_18, 1_19, 1_20, 1_21, 1_22, 1_23, 1_24, 1_25, 1_26, 1_27, 1_28, 1_29, 1_30, 1_31 |
| Case Name |
Status |
Exec Time |
Memory |
| 0_00 |
AC |
1 ms |
1608 KiB |
| 0_01 |
AC |
0 ms |
1748 KiB |
| 0_02 |
AC |
0 ms |
1712 KiB |
| 0_03 |
AC |
0 ms |
1744 KiB |
| 1_00 |
AC |
0 ms |
1624 KiB |
| 1_01 |
AC |
0 ms |
1724 KiB |
| 1_02 |
AC |
242 ms |
77096 KiB |
| 1_03 |
AC |
232 ms |
76288 KiB |
| 1_04 |
AC |
201 ms |
75068 KiB |
| 1_05 |
AC |
204 ms |
75088 KiB |
| 1_06 |
AC |
199 ms |
74828 KiB |
| 1_07 |
AC |
202 ms |
75224 KiB |
| 1_08 |
AC |
201 ms |
74748 KiB |
| 1_09 |
AC |
203 ms |
75276 KiB |
| 1_10 |
AC |
200 ms |
74552 KiB |
| 1_11 |
AC |
205 ms |
75276 KiB |
| 1_12 |
AC |
202 ms |
74440 KiB |
| 1_13 |
AC |
205 ms |
74468 KiB |
| 1_14 |
AC |
213 ms |
73900 KiB |
| 1_15 |
AC |
214 ms |
73900 KiB |
| 1_16 |
AC |
218 ms |
71328 KiB |
| 1_17 |
AC |
230 ms |
72932 KiB |
| 1_18 |
AC |
221 ms |
72376 KiB |
| 1_19 |
AC |
228 ms |
72180 KiB |
| 1_20 |
AC |
230 ms |
71128 KiB |
| 1_21 |
AC |
233 ms |
72036 KiB |
| 1_22 |
AC |
230 ms |
71748 KiB |
| 1_23 |
AC |
233 ms |
71544 KiB |
| 1_24 |
AC |
223 ms |
70744 KiB |
| 1_25 |
AC |
234 ms |
71664 KiB |
| 1_26 |
AC |
227 ms |
72392 KiB |
| 1_27 |
AC |
230 ms |
70724 KiB |
| 1_28 |
AC |
232 ms |
73740 KiB |
| 1_29 |
AC |
247 ms |
73192 KiB |
| 1_30 |
AC |
232 ms |
73840 KiB |
| 1_31 |
AC |
237 ms |
77176 KiB |