結果
問題 | No.2987 Colorful University of Tree |
ユーザー |
👑 |
提出日時 | 2024-12-12 02:19:44 |
言語 | C (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 594 ms / 5,000 ms |
コード長 | 8,558 bytes |
コンパイル時間 | 518 ms |
コンパイル使用メモリ | 39,136 KB |
実行使用メモリ | 52,304 KB |
最終ジャッジ日時 | 2024-12-12 02:20:03 |
合計ジャッジ時間 | 19,196 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 41 |
ソースコード
#include <stdio.h>#include <stdlib.h>#define MT_N 624#define MT_M 397#define MT_MATRIX_A 0x9908b0dfUL#define MT_UPPER_MASK 0x80000000UL#define MT_LOWER_MASK 0x7fffffffULstatic unsigned int mt[MT_N];static int mti = MT_N + 1;void init_genrand(unsigned int s){mt[0] = s & 0xffffffffUL;for (mti = 1; mti < MT_N; mti++) {mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);mt[mti] &= 0xffffffffUL;}}unsigned int genrand(){unsigned int y;static unsigned int mag01[2] = {0x0UL, MT_MATRIX_A};if (mti >= MT_N) {int kk;if (mti == MT_N + 1) init_genrand(5489UL);for (kk = 0; kk < MT_N - MT_M; kk++) {y = (mt[kk] & MT_UPPER_MASK) | (mt[kk+1] & MT_LOWER_MASK);mt[kk] = mt[kk+MT_M] ^ (y >> 1) ^ mag01[y&0x1UL];}for (; kk < MT_N - 1; kk++) {y = (mt[kk] & MT_UPPER_MASK) | (mt[kk+1] & MT_LOWER_MASK);mt[kk] = mt[kk+(MT_M-MT_N)] ^ (y >> 1) ^ mag01[y&0x1UL];}y = (mt[MT_N-1] & MT_UPPER_MASK) | (mt[0] & MT_LOWER_MASK);mt[MT_N-1] = mt[MT_M-1] ^ (y >> 1) ^ mag01[y&0x1UL];mti = 0;}y = mt[mti++];y ^= (y >> 11);y ^= (y << 7) & 0x9d2c5680UL;y ^= (y << 15) & 0xefc60000UL;y ^= (y >> 18);return y;}void shuffle_permutation(int N, int p[], int K){int i, j;while (K--) {i = genrand() % N + 1;j = genrand() % N + 1;if (i != j) {p[i] ^= p[j];p[j] ^= p[i];p[i] ^= p[j];}}}void chmax(int *a, int b){if (*a < b) *a = b;}typedef struct {int key, id;} data;typedef struct {data obj[200001];int size;} max_heap;void push(max_heap* h, data x){int i = ++(h->size), j = i >> 1;data tmp;h->obj[i] = x;while (j > 0) {if (h->obj[i].key > h->obj[j].key) {tmp = h->obj[j];h->obj[j] = h->obj[i];h->obj[i] = tmp;i = j;j >>= 1;} else break;}}data pop(max_heap* h){int i = 1, j = 2;data output = h->obj[1], tmp;h->obj[1] = h->obj[(h->size)--];while (j <= h->size) {if (j < h->size && h->obj[j^1].key > h->obj[j].key) j ^= 1;if (h->obj[j].key > h->obj[i].key) {tmp = h->obj[j];h->obj[j] = h->obj[i];h->obj[i] = tmp;i = j;j <<= 1;} else break;}return output;}const int inf = -1;int leaf[200001];typedef struct {int left, right, max;} seg_node;void init_node(seg_node v[], int k, int l, int r){v[k].left = l;v[k].right = r;v[k].max = inf;if (l < r) {init_node(v, k << 1, l, (l + r) / 2);init_node(v, (k << 1) ^ 1, (l + r) / 2 + 1, r);} else leaf[l] = k;}void update_node(seg_node v[], int k, int x){int i, j = leaf[k];v[j].max = x;for (i = j >> 1; i > 0; j = i, i >>= 1) v[i].max = (v[j].max > v[j^1].max)? v[j].max: v[j^1].max;}int get_max(seg_node v[], int k, int l, int r){int tmp[2];if (v[k].right < l || v[k].left > r) return inf;else if (v[k].left >= l && v[k].right <= r) return v[k].max;else {tmp[0] = get_max(v, k << 1, l, r);tmp[1] = get_max(v, (k << 1) ^ 1, l, r);return (tmp[0] < tmp[1])? tmp[1]: tmp[0];}}int BS_left(seg_node v[], int k, int l, int r, int x){int tmp;if (v[k].max < x || v[k].right < l || v[k].left > r) return r + 1;else if (v[k].left == v[k].right) return v[k].left;else {tmp = BS_left(v, k << 1, l, r, x);if (tmp <= r) return tmp;else return BS_left(v, (k << 1) ^ 1, l, r, x);}}int bin_packing(int N, int deg[], int F[]){int u, Q;for (Q = 1; Q * Q < (N - 1) * 2; Q++);for (u = 1; u <= N; u++) chmax(&Q, deg[u]);if ((long long)(Q - 1) * (Q - 1) < (N - 1) * 2) {int i, j, k, u, q, max;static int dp[1001], num[1001], use[1001];for (i = 1; i <= Q; i++) num[i] = 0;for (u = 1; u <= N; u++) {F[u] = 0;num[deg[u]]++;}for (q = 1; q <= Q; q++) {for (i = 1; i <= Q; i++) if (num[i] > 0) break;if (i > Q) break;for (i = 1; i <= Q; i++) use[i] = 0;for (j = 1, dp[0] = 0; j <= Q; j++) dp[j] = -1;for (i = Q, max = 0; i >= 1 && max < Q; i--) {for (j = max; j >= 0; j--) {if (dp[j] < 0) continue;for (k = 1; k <= num[i] && j + i * k <= Q; k++) {if (dp[j+i*k] < 0) {dp[j+i*k] = i;chmax(&max, j + i * k);}}}}for (j = Q; dp[j] < 0; j--);while (j > 0) {use[dp[j]]++;j -= dp[j];}for (u = 1; u <= N; u++) {if (F[u] == 0 && use[deg[u]] > 0) {F[u] = q;use[deg[u]]--;num[deg[u]]--;}}}for (u = 1; u <= N; u++) if (F[u] == 0) break;if (u > N) return Q;Q++;for (i = 1; i <= Q; i++) num[i] = 0;for (u = 1; u <= N; u++) {F[u] = 0;num[deg[u]]++;}for (q = 1; q <= Q; q++) {for (i = 1; i <= Q; i++) if (num[i] > 0) break;if (i > Q) break;for (i = 1; i <= Q; i++) use[i] = 0;for (j = 1, dp[0] = 0; j <= Q; j++) dp[j] = -1;for (i = Q, max = 0; i >= 1 && max < Q; i--) {for (j = max; j >= 0; j--) {if (dp[j] < 0) continue;for (k = 1; k <= num[i] && j + i * k <= Q; k++) {if (dp[j+i*k] < 0) {dp[j+i*k] = i;chmax(&max, j + i * k);}}}}for (j = Q; dp[j] < 0; j--);while (j > 0) {use[dp[j]]++;j -= dp[j];}for (u = 1; u <= N; u++) {if (F[u] == 0 && use[deg[u]] > 0) {F[u] = q;use[deg[u]]--;num[deg[u]]--;}}}for (u = 1; u <= N; u++) if (F[u] == 0) exit(-1);return Q;}int i;static seg_node v[524288];init_node(v, 1, 1, Q);for (i = 1; i <= Q; i++) update_node(v, i, Q);static max_heap h;data d;h.size = 0;for (u = 1; u <= N; u++) {d.key = deg[u];d.id = u;push(&h, d);}while (h.size > 0) {d = pop(&h);u = d.id;i = BS_left(v, 1, 1, Q, deg[u]);F[u] = i;update_node(v, i, get_max(v, 1, i, i) - deg[u]);}return Q;}int solve(int N, int deg[], int *adj[], int F[], int *FF[]){int Q = bin_packing(N, deg, F);int i, u;static int ed[200001][2][2];for (i = 1; i <= N - 1; i++) ed[i][0][0] = 0;for (u = 1; u <= N; u++) {for (i = 1; i <= deg[u]; i++) {if (ed[adj[u][i]][0][0] == 0) {ed[adj[u][i]][0][0] = u;ed[adj[u][i]][0][1] = i;} else {ed[adj[u][i]][1][0] = u;ed[adj[u][i]][1][1] = i;}}}int j, k;static int p[200001], *q[200001], *qq[200001], num[200001];for (i = 1; i <= Q; i++) num[i] = 0;for (u = 1; u <= N; u++) num[F[u]] += deg[u];for (i = 1; i <= Q; i++) {q[i] = (int*)malloc(sizeof(int) * (num[i] + 1));qq[i] = (int*)malloc(sizeof(int) * (num[i] + 1));num[i] = 0;}for (u = 1; u <= N; u++) {for (i = 1; i <= deg[u]; i++) {q[F[u]][++num[F[u]]] = u;qq[F[u]][num[F[u]]] = i;}}for (i = 1; i <= Q; i++) p[i] = i;shuffle_permutation(Q, p, Q * 10);for (i = 1; i <= Q; i++) {shuffle_permutation(Q, p, 100);for (j = 1, k = genrand() % Q + 1; j <= num[i]; j++, k++) {if (k > Q) k -= Q;FF[q[i][j]][qq[i][j]] = p[k];}}int w, r, ww, jj;for (k = 1; k <= N - 1; k++) {u = ed[k][0][0];i = ed[k][0][1];w = ed[k][1][0];j = ed[k][1][1];while (FF[u][i] == FF[w][j]) {// printf("[%d %d %d %d]\n", u, i, w, j);if (num[F[w]] == 1) {FF[w][j]++;if (FF[w][j] > Q) FF[w][j] -= Q;} else {do {r = genrand() % num[F[w]] + 1;} while (q[F[w]][r] == w && qq[F[w]][r] == j);ww = q[F[w]][r];jj = qq[F[w]][r];FF[w][j] ^= FF[ww][jj];FF[ww][jj] ^= FF[w][j];FF[w][j] ^= FF[ww][jj];u = ww;i = jj;w = ed[adj[u][i]][0][0] ^ ed[adj[u][i]][1][0] ^ u;j = ed[adj[u][i]][0][1] ^ ed[adj[u][i]][1][1] ^ i;}}}for (i = 1; i <= Q; i++) {free(q[i]);free(qq[i]);}return Q;}int main(){int T, i, u, N, deg[200001], *adj[200001], F[200001], *FF[200001];scanf("%d", &T);while (T--) {scanf("%d", &N);for (u = 1; u <= N; u++) {scanf("%d", &(deg[u]));adj[u] = (int*)malloc(sizeof(int) * (deg[u] + 1));FF[u] = (int*)malloc(sizeof(int) * (deg[u] + 1));for (i = 1; i <= deg[u]; i++) {scanf("%d", &(adj[u][i]));}}printf("%d\n", solve(N, deg, adj, F, FF));for (u = 1; u <= N; u++) {printf("%d", F[u]);for (i = 1; i <= deg[u]; i++) printf(" %d", FF[u][i]);printf("\n");}for (u = 1; u <= N; u++) {free(adj[u]);free(FF[u]);}}/*scanf("%d", &N);while (1) {for (u = 1; u <= N; u++) deg[u] = 0;for (u = 2; u <= N; u++) {deg[u]++;deg[genrand() % (u - 1) + 1]++;}bin_packing(N, deg, F);printf("a");}*/fflush(stdout);return 0;}