#pragma GCC optimize ("Ofast") #pragma GCC optimize ("unroll-loops") #include <bits/stdc++.h> using namespace std; using ll = long long; using db = long double; using ull = unsigned long long; #define int long long using pi = pair<int, int>; using pl = pair<ll, ll>; using vi = vector<int>; using vl = vector<ll>; using vpi = vector<pi>; using vpl = vector<pl>; #define pb push_back #define eb emplace_back #define mp make_pair #define f first #define s second #define tcT template<class T #define tcTU tcT, class U #define sz(x) int((x).size()) #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define rep(i,a,b) for(int i = (a); i < (b); i++) #define rrep(i,a,b) for(int i = (b) - 1; i >= (a); i--) template <int mod> struct modint { static constexpr bool is_modint = true; int val; constexpr modint(const ll val = 0) noexcept : val(val >= 0 ? val % mod : (mod - (-val) % mod) % mod) {} bool operator<(const modint &other) const { return val < other.val; } // To use std::map modint &operator+=(const modint &p) { if ((val += p.val) >= mod) val -= mod; return *this; } modint &operator-=(const modint &p) { if ((val += mod - p.val) >= mod) val -= mod; return *this; } modint &operator*=(const modint &p) { val = val * p.val % mod; return *this; } modint &operator/=(const modint &p) { *this *= p.inverse(); return *this; } modint operator-() const { return modint(-val); } modint operator+(const modint &p) const { return modint(*this) += p; } modint operator-(const modint &p) const { return modint(*this) -= p; } modint operator*(const modint &p) const { return modint(*this) *= p; } modint operator/(const modint &p) const { return modint(*this) /= p; } bool operator==(const modint &p) const { return val == p.val; } bool operator!=(const modint &p) const { return val != p.val; } modint inverse() const { int a = val, b = mod, u = 1, v = 0, t; while (b > 0) { t = a / b; swap(a -= t * b, b), swap(u -= t * v, v); } return modint(u); } modint pow(int64_t n) const { modint ret(1), mul(val); while (n > 0) { if (n & 1) ret *= mul; mul *= mul; n >>= 1; } return ret; } static constexpr int get_mod() { return mod; } }; uint32_t get(){ uint32_t ans = 0; uint8_t c; while((c = getchar_unlocked() ^ 48) < 10){ ans *= 10; ans += c; } return ans; } constexpr int MOD = 1e9+7; using mi = modint<MOD>; signed main() { uint32_t n; n = get(); mi a[n][n]; uint32_t in[n]; for (uint32_t i = 0; i < n; i++) { in[i] = get(); } for (uint32_t i = 0; i < n; i++) { for (uint32_t j = 0; j < n; j++) { a[i][j] = MOD-__gcd(in[i], in[j]); } for (uint32_t j = 0; j < n; j++) { a[i][i] += __gcd(in[i], in[j]); } } n--; mi result = 1; for (uint32_t i = 0; i < n; i++) { result *= a[i][i]; mi curinv = a[i][i].inverse(); for (uint32_t k = i+1; k < n; k++) { mi cur = curinv * a[i][k]; for (uint32_t j = k; j < n; j++) { a[k][j] -= a[i][j] * cur; } } } cout << result.val << "\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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #pragma GCC optimize ("Ofast") #pragma GCC optimize ("unroll-loops") #include <bits/stdc++.h> using namespace std; using ll = long long; using db = long double; using ull = unsigned long long; #define int long long using pi = pair<int, int>; using pl = pair<ll, ll>; using vi = vector<int>; using vl = vector<ll>; using vpi = vector<pi>; using vpl = vector<pl>; #define pb push_back #define eb emplace_back #define mp make_pair #define f first #define s second #define tcT template<class T #define tcTU tcT, class U #define sz(x) int((x).size()) #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define rep(i,a,b) for(int i = (a); i < (b); i++) #define rrep(i,a,b) for(int i = (b) - 1; i >= (a); i--) template <int mod> struct modint { static constexpr bool is_modint = true; int val; constexpr modint(const ll val = 0) noexcept : val(val >= 0 ? val % mod : (mod - (-val) % mod) % mod) {} bool operator<(const modint &other) const { return val < other.val; } // To use std::map modint &operator+=(const modint &p) { if ((val += p.val) >= mod) val -= mod; return *this; } modint &operator-=(const modint &p) { if ((val += mod - p.val) >= mod) val -= mod; return *this; } modint &operator*=(const modint &p) { val = val * p.val % mod; return *this; } modint &operator/=(const modint &p) { *this *= p.inverse(); return *this; } modint operator-() const { return modint(-val); } modint operator+(const modint &p) const { return modint(*this) += p; } modint operator-(const modint &p) const { return modint(*this) -= p; } modint operator*(const modint &p) const { return modint(*this) *= p; } modint operator/(const modint &p) const { return modint(*this) /= p; } bool operator==(const modint &p) const { return val == p.val; } bool operator!=(const modint &p) const { return val != p.val; } modint inverse() const { int a = val, b = mod, u = 1, v = 0, t; while (b > 0) { t = a / b; swap(a -= t * b, b), swap(u -= t * v, v); } return modint(u); } modint pow(int64_t n) const { modint ret(1), mul(val); while (n > 0) { if (n & 1) ret *= mul; mul *= mul; n >>= 1; } return ret; } static constexpr int get_mod() { return mod; } }; uint32_t get(){ uint32_t ans = 0; uint8_t c; while((c = getchar_unlocked() ^ 48) < 10){ ans *= 10; ans += c; } return ans; } constexpr int MOD = 1e9+7; using mi = modint<MOD>; signed main() { uint32_t n; n = get(); mi a[n][n]; uint32_t in[n]; for (uint32_t i = 0; i < n; i++) { in[i] = get(); } for (uint32_t i = 0; i < n; i++) { for (uint32_t j = 0; j < n; j++) { a[i][j] = MOD-__gcd(in[i], in[j]); } for (uint32_t j = 0; j < n; j++) { a[i][i] += __gcd(in[i], in[j]); } } n--; mi result = 1; for (uint32_t i = 0; i < n; i++) { result *= a[i][i]; mi curinv = a[i][i].inverse(); for (uint32_t k = i+1; k < n; k++) { mi cur = curinv * a[i][k]; for (uint32_t j = k; j < n; j++) { a[k][j] -= a[i][j] * cur; } } } cout << result.val << "\n"; return 0; } |