#include <bits/stdc++.h> using namespace std; const int MOD = 1'000'000'007; int t[5005]; int kraw[5005][5005]; int n; int r[5005]; int Find(int x) { if (r[x] == x) return x; return r[x] = Find(r[x]); } int Union(int a, int b) { int ra = Find(a); int rb = Find(b); if (ra != rb) { r[ra] = rb; return 1; } return 0; } vector<pair<int, int>> edges; int res = 0; vector<pair<int, int>> to_take; int check() { for (int i = 1; i <= n; i++) { r[i] = i; } int spojne = n; for (auto i : to_take) { if (Union(i.first, i.second)) spojne--; } return spojne == 1; } void baktrak(int wzialem, int mult, int edge_idx) { if (wzialem == n - 1) { res += check() * mult; if (res >= MOD) res -= MOD; return; } for (int i = edge_idx; i < edges.size(); i++) { int a = edges[i].first; int b = edges[i].second; to_take.push_back({a, b}); baktrak(wzialem + 1, 1LL * mult * kraw[a][b] % MOD, i + 1); to_take.pop_back(); } } int32_t main() { ios_base::sync_with_stdio(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> t[i]; } for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { edges.push_back({i, j}); } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i != j) kraw[i][j] = __gcd(t[i], t[j]); } } baktrak(0, 1, 0); cout << res << "\n"; }
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 72 73 74 75 76 77 78 79 | #include <bits/stdc++.h> using namespace std; const int MOD = 1'000'000'007; int t[5005]; int kraw[5005][5005]; int n; int r[5005]; int Find(int x) { if (r[x] == x) return x; return r[x] = Find(r[x]); } int Union(int a, int b) { int ra = Find(a); int rb = Find(b); if (ra != rb) { r[ra] = rb; return 1; } return 0; } vector<pair<int, int>> edges; int res = 0; vector<pair<int, int>> to_take; int check() { for (int i = 1; i <= n; i++) { r[i] = i; } int spojne = n; for (auto i : to_take) { if (Union(i.first, i.second)) spojne--; } return spojne == 1; } void baktrak(int wzialem, int mult, int edge_idx) { if (wzialem == n - 1) { res += check() * mult; if (res >= MOD) res -= MOD; return; } for (int i = edge_idx; i < edges.size(); i++) { int a = edges[i].first; int b = edges[i].second; to_take.push_back({a, b}); baktrak(wzialem + 1, 1LL * mult * kraw[a][b] % MOD, i + 1); to_take.pop_back(); } } int32_t main() { ios_base::sync_with_stdio(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> t[i]; } for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { edges.push_back({i, j}); } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i != j) kraw[i][j] = __gcd(t[i], t[j]); } } baktrak(0, 1, 0); cout << res << "\n"; } |