// Kacper Orszulak #include <cstdio> #include <vector> #include <string> #include <algorithm> using namespace std; __uint128_t gcd(__uint128_t a, __uint128_t b) { while (b) { a %= b; swap(a, b); } return a; } struct fract_t { __uint128_t p = 0, q = 1; fract_t& operator+=(const fract_t &another); }; fract_t& fract_t::operator+=(const fract_t &another) { const __uint128_t g = gcd(q, another.q); const __uint128_t new_q = q / g * another.q; p = p*(new_q/q) + another.p*(new_q/another.q); q = new_q; return *this; } int main(void) { size_t n; scanf("%zu", &n); vector<vector<size_t>> al(n); for (vector<size_t> &r : al) { size_t k; scanf("%zu", &k); r.resize(k); for (size_t &w : r) scanf("%zu", &w), --w; } __uint128_t result = 1; vector<fract_t> presence(n); presence[0].p = 1; presence[0].q = 1; for (size_t v = 0; v < n; ++v) { fract_t &f = presence[v]; if (f.p == 0) continue; result = result / gcd(result, f.q) * f.q; f.q *= static_cast<__uint128_t>(al[v].size()); const __uint128_t g = gcd(f.p, f.q); f.p /= g; f.q /= g; for (const size_t w : al[v]) { presence[w] += f; } } string s; while (result > 0) { const char rem = static_cast<char>(result%10); s += '0'+rem; // printf("%d", rem); result /= 10; } reverse(s.begin(), s.end()); printf("%s\n", s.c_str()); // printf("\n"); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | // Kacper Orszulak #include <cstdio> #include <vector> #include <string> #include <algorithm> using namespace std; __uint128_t gcd(__uint128_t a, __uint128_t b) { while (b) { a %= b; swap(a, b); } return a; } struct fract_t { __uint128_t p = 0, q = 1; fract_t& operator+=(const fract_t &another); }; fract_t& fract_t::operator+=(const fract_t &another) { const __uint128_t g = gcd(q, another.q); const __uint128_t new_q = q / g * another.q; p = p*(new_q/q) + another.p*(new_q/another.q); q = new_q; return *this; } int main(void) { size_t n; scanf("%zu", &n); vector<vector<size_t>> al(n); for (vector<size_t> &r : al) { size_t k; scanf("%zu", &k); r.resize(k); for (size_t &w : r) scanf("%zu", &w), --w; } __uint128_t result = 1; vector<fract_t> presence(n); presence[0].p = 1; presence[0].q = 1; for (size_t v = 0; v < n; ++v) { fract_t &f = presence[v]; if (f.p == 0) continue; result = result / gcd(result, f.q) * f.q; f.q *= static_cast<__uint128_t>(al[v].size()); const __uint128_t g = gcd(f.p, f.q); f.p /= g; f.q /= g; for (const size_t w : al[v]) { presence[w] += f; } } string s; while (result > 0) { const char rem = static_cast<char>(result%10); s += '0'+rem; // printf("%d", rem); result /= 10; } reverse(s.begin(), s.end()); printf("%s\n", s.c_str()); // printf("\n"); return 0; } |