Submission #71105109


Source Code Expand

Copy
#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;
}
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
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
AC × 36
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


2025-11-22 (Sat)
09:14:42 +09:00