// 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; } |
English