結果

問題 No.2987 Colorful University of Tree
ユーザー 👑 ygussany
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#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 0x7fffffffUL
static 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;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0