結果
問題 | No.382 シャイな人たち (2) |
ユーザー | Min_25 |
提出日時 | 2016-06-19 13:31:46 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 786 ms / 8,000 ms |
コード長 | 8,332 bytes |
コンパイル時間 | 1,237 ms |
コンパイル使用メモリ | 89,468 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-10-11 05:20:16 |
合計ジャッジ時間 | 15,773 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 786 ms
5,248 KB |
testcase_01 | AC | 759 ms
5,248 KB |
testcase_02 | AC | 637 ms
5,248 KB |
testcase_03 | AC | 617 ms
5,248 KB |
testcase_04 | AC | 617 ms
5,248 KB |
testcase_05 | AC | 630 ms
5,248 KB |
testcase_06 | AC | 562 ms
5,248 KB |
testcase_07 | AC | 702 ms
5,248 KB |
testcase_08 | AC | 560 ms
5,248 KB |
testcase_09 | AC | 572 ms
5,248 KB |
testcase_10 | AC | 585 ms
5,248 KB |
testcase_11 | AC | 622 ms
5,248 KB |
testcase_12 | AC | 570 ms
5,248 KB |
testcase_13 | AC | 643 ms
5,248 KB |
testcase_14 | AC | 595 ms
5,248 KB |
testcase_15 | AC | 653 ms
5,248 KB |
testcase_16 | AC | 541 ms
5,248 KB |
testcase_17 | AC | 467 ms
5,248 KB |
testcase_18 | AC | 697 ms
5,248 KB |
testcase_19 | AC | 661 ms
5,248 KB |
testcase_20 | AC | 2 ms
5,248 KB |
ソースコード
#include <cstdio> #include <cassert> #include <cmath> #include <cstring> #include <algorithm> #include <iostream> #include <vector> #include <map> #include <set> #include <functional> #include <tuple> #define _fetch(_1, _2, _3, _4, name, ...) name #define rep2(i, n) rep3(i, 0, n) #define rep3(i, a, b) rep4(i, a, b, 1) #define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c)) #define rep(...) _fetch(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__) using namespace std; using i64 = long long; using u8 = unsigned char; using u32 = unsigned; using u64 = unsigned long long; using f80 = long double; using u128 = __uint128_t; const u32 N_MAX = 120; int degs[N_MAX + 1]; u128 V_deg[N_MAX + 2]; u128 edges[N_MAX + 1]; inline int ctz(u128 n) { if (u64(n)) return __builtin_ctzll(u64(n)); else return 64 + __builtin_ctzll(u64(n >> 64)); } inline int pop_count(u128 n) { if (u64(n)) return __builtin_popcountll(u64(n)) + __builtin_popcountll(u64(n >> 64)); else return __builtin_popcountll(u64(n >> 64)); } inline void delete_v(u128 G, int v) { auto Nv = edges[v] & G; while (Nv) { auto fy = Nv & -Nv; int y = ctz(fy); V_deg[degs[y]--] ^= fy; V_deg[degs[y]] ^= fy; Nv ^= fy; } } inline void insert_v(u128 G, int v) { auto Nv = edges[v] & G; while (Nv) { auto fy = Nv & -Nv; int y = ctz(fy); V_deg[degs[y]++] ^= fy; V_deg[degs[y]] ^= fy; Nv ^= fy; } } inline void delete_V(u128 G, u128 V) { G ^= V; for (; V; V &= V - 1) { delete_v(G, ctz(V)); } } inline void insert_V(u128 G, u128 V) { G ^= V; for (; V; V &= V - 1) { insert_v(G, ctz(V)); } } inline int max_deg_vertex(u128 G, u128 S, int beg) { for (int deg = beg; ; ++deg) { u128 Vd = V_deg[deg] & G; if ((S |= Vd) != G) continue; return ctz(Vd); } } bool is_clique(u128 G) { auto V = G; while (V) { auto fv = V & -V; auto Nv = fv | (edges[ctz(fv)] & G); if (Nv != G) return false; V ^= fv; } return true; } u128 calc_N2v(u128 G, int v, u128 Nv) { auto fv = u128(1) << v; auto Nv_back = Nv; auto N2v = u128(0); for (; Nv; Nv &= Nv - 1) { N2v |= edges[ctz(Nv)]; } return (N2v & G) & ~(Nv_back | fv); } u128 mirror(u128 G, int v, u128 Nv, u128 N2v) { u128 ret = 0; while (N2v) { auto fw = N2v & -N2v; int w = ctz(fw); auto Nw = fw ^ (edges[w] & G); auto Nv_Nw = Nv & ~Nw; if (is_clique(Nv_Nw)) ret |= fw; N2v ^= fw; } return ret; } u128 connected_component(u128 G) { auto fv = G & -G; u128 U = 0; u128 V = 0; while (fv) { int v = ctz(fv); U |= fv; V |= (edges[v] & G) & ~U; V ^= fv = V & -V; } return U; } int vertices[N_MAX]; // Naive: O(3^(n/3)) ~= O(1.4422^n) int mis1(u128 G) { if (G == 0) return 0; for (int deg = 0; ; ++deg) if (V_deg[deg] & G) { int i_max = 0; auto fv = V_deg[deg] & G; fv &= -fv; int v = ctz(fv); auto Nv = fv | (edges[v] & G); while (Nv) { auto fy = Nv & -Nv; int y = ctz(fy); auto Ny = edges[y] & G; delete_v(G, y); i_max = max(i_max, mis1(G ^ (Ny | fy))); insert_v(G, y); Nv ^= fy; } return 1 + i_max; } } // O(?) int mis3(u128 G, int idx=0) { if (G == 0) return 0; // d(v) <= 1 const u128 V01 = (V_deg[0] | V_deg[1]) & G; if (V01) { auto fv = V01 & -V01; int v = ctz(fv); auto Nv = edges[v] & G; delete_V(G, Nv); vertices[idx] = v; int ret = 1 + mis3(G ^ (Nv | fv), idx + 1); insert_V(G, Nv); return ret; } int vertices_back[N_MAX]; // d(v) == 2 const u128 V2 = V_deg[2] & G; if (V2) { auto fv = V2 & -V2; int v = ctz(fv); auto Nv = edges[v] & G; auto fu1 = Nv & -Nv; Nv ^= fu1; int u1 = ctz(fu1); auto fu2 = Nv; Nv ^= fu1; int u2 = ctz(fu2); auto Nu1 = edges[u1] & G; if (Nu1 & fu2) { delete_V(G, Nv); vertices[idx] = v; int ret = 1 + mis3(G ^ (Nv | fv), idx + 1); insert_V(G, Nv); return ret; } else { auto N2v = calc_N2v(G, v, Nv); if ((N2v & (N2v - 1)) == 1) { auto fw = N2v; int w = ctz(fw); auto Nw = edges[w] & G; delete_V(G, Nv | Nw); vertices[idx] = v; vertices[idx + 1] = w; int ret1 = 2 + mis3(G ^ (fv | Nv | fw | Nw), idx + 2); copy(vertices + idx, vertices + idx + ret1, vertices_back); insert_V(G, Nv | Nw); delete_V(G, fw); vertices[idx] = u1; vertices[idx + 1] = u2; int ret2 = 2 + mis3(G ^ (fv | Nv | fw), idx + 2); insert_V(G, fw); if (ret1 > ret2) { copy(vertices_back, vertices_back + ret1, vertices + idx); } return max(ret1, ret2); } else { delete_V(G, Nv); vertices[idx] = v; int ret1 = 1 + mis3(G ^ (fv | Nv), idx + 1); copy(vertices + idx, vertices + idx + ret1, vertices_back); insert_V(G, Nv); auto Mv = mirror(G, v, Nv, N2v); delete_V(G, Mv | fv); int ret2 = mis3(G ^ (fv | Mv), idx); insert_V(G, Mv | fv); if (ret1 > ret2) { copy(vertices_back, vertices_back + ret1, vertices + idx); } return max(ret1, ret2); } } } auto V3 = V_deg[3] & G; if (V3) { auto fv = V3 & -V3; int v = ctz(fv); auto Nv = edges[v] & G; auto fu1 = Nv & -Nv; Nv ^= fu1; int u1 = ctz(fu1); auto fu2 = Nv & -Nv; Nv ^= fu2; int u2 = ctz(fu2); auto fu3 = Nv; Nv ^= fu1 | fu2; auto Nu1 = edges[u1] & G; auto Nu2 = edges[u2] & G; bool b12 = Nu1 & fu2; bool b13 = Nu1 & fu3; bool b23 = Nu2 & fu3; if (b12 && b13 && b23) { delete_V(G, Nv); vertices[idx] = v; int ret = 1 + mis3(G ^ (Nv | fv), idx + 1); insert_V(G, Nv); return ret; } else if (b12 || b13 || b23) { delete_V(G, Nv); vertices[idx] = v; int ret1 = 1 + mis3(G ^ (Nv | fv), idx + 1); copy(vertices + idx, vertices + idx + ret1, vertices_back); insert_V(G, Nv); auto Mv = mirror(G, v, Nv, calc_N2v(G, v, Nv)); delete_V(G, Mv | fv); int ret2 = mis3(G ^ (Mv | fv), idx); insert_V(G, Mv | fv); if (ret1 > ret2) { copy(vertices_back, vertices_back + ret1, vertices + idx); } return max(ret1, ret2); } else { /* */ } } // d(v) >= 3 if (1) { int v = max_deg_vertex(G, V2, 3); auto fv = u128(1) << v; auto Nv = edges[v] & G; // G \ v delete_v(G, v); int ret1 = mis3(G ^ fv, idx); copy(vertices + idx, vertices + idx + ret1, vertices_back); insert_v(G, v); // G \ N(v) delete_V(G, Nv); vertices[idx] = v; int ret2 = 1 + mis3(G ^ (Nv | fv), idx + 1); insert_V(G, Nv); if (ret1 > ret2) { copy(vertices_back, vertices_back + ret1, vertices + idx); } return max(ret1, ret2); } } int mis30(u128 G) { int ret = 0; while (G) { auto C = connected_component(G); ret += mis3(C, ret); G ^= C; } return ret; } struct Rand { Rand(u32 seed) : x(seed) {} u32 next() { return x = u64(x) * 12345 % 1000003; } u32 x; }; int gene_graph(int S) { auto gene = Rand(S); int N = gene.next() % N_MAX + 2; int P = gene.next(); // fprintf(stderr, "N: %u, P: %u\n", N, P); rep(i, N) { degs[i] = V_deg[i] = edges[i] = 0; } rep(i, N) rep(j, i + 1, N) { int X = gene.next(); if (X >= P) { edges[i] |= u128(1) << j; degs[i]++; edges[j] |= u128(1) << i; degs[j]++; // fprintf(stderr, "S: %u, E: %u <-> %u (%u)\n", S, i, j, X); } } rep(i, N) V_deg[degs[i]] |= u128(1) << i; return N; } void solve() { int S; // clock_t worst = 0; while (~scanf("%d", &S)) { int N = gene_graph(S); auto G = (u128(1) << N) - 1; // clock_t beg = clock(); int len = mis3(G); // clock_t end = clock(); // if (end - beg > worst) { // worst = end - beg; // printf("%u: %d %.6f\n", S, pop_count(G), double(worst) / CLOCKS_PER_SEC); // } // continue; if (len == N) { puts("-1"); } else { printf("%u\n", len + 1); printf("%u", vertices[0] + 1); rep(i, 1, len) printf(" %u", vertices[i] + 1); puts(""); } } } int main() { clock_t beg = clock(); solve(); clock_t end = clock(); fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC); return 0; }