#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"; } |
English