#include <bits/stdc++.h> #define ll long long #define fors(u, n, s) for(ll u=(s); u < (n); u++) #define foru(u, n) fors(u, n, 0) #define ir(a, b, x) (((a) <= (x)) && ((x) <= (b))) #define vec vector #define pb push_back #define pint pair<int, int> #define f first #define s second using namespace std; #define N 5000 #define M 1000000007 int n; int nwd(int a, int b){ ///ASSERTING A>B if(b==0) return a; return nwd(b, a%b); } int arr[N]; ll lap[N][N]; ll bin_pow(ll a, int b){ ll ans=1; while(b!=0){ if(b & 1) ans*=a; b=b>>1; a=a*a; a=a%M; ans=ans%M; } return ans; } ll inv(int x){ return bin_pow(x, M-2); } ll det(int k){ /// det of lap truncated to range (k, ..., n-1) //cout << k << endl; if(k==n-1) return lap[k][k]; int swp = -1; fors(i, n, k){ swp=i; if(lap[k][i]!=0) break; } fors(i, n, k) swap(lap[i][k], lap[i][swp]); if(swp!=k) lap[k][k]=(M-lap[k][k])%M; ll mult = inv(lap[k][k]); fors(j, n, k+1){ ///iterating by rows ll mult_ = mult*lap[k][j]; mult_=mult_%M; mult_=M-mult_; mult_=mult_%M; fors(i, n, k){ lap[i][j] += lap[i][k]*mult_; lap[i][j]=lap[i][j]%M; } } return (lap[k][k]*det(k+1))%M; } int main() { cin >> n; foru(i, n) cin >> arr[i]; foru(i, n) lap[i][i]=0; foru(i, n) foru(j, n){ if(i==j) continue; ll edges = nwd(max(arr[i], arr[j]), min(arr[i], arr[j])); lap[i][j]=(M-edges)%M; lap[i][i]+=edges; } cout << det(1); 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 | #include <bits/stdc++.h> #define ll long long #define fors(u, n, s) for(ll u=(s); u < (n); u++) #define foru(u, n) fors(u, n, 0) #define ir(a, b, x) (((a) <= (x)) && ((x) <= (b))) #define vec vector #define pb push_back #define pint pair<int, int> #define f first #define s second using namespace std; #define N 5000 #define M 1000000007 int n; int nwd(int a, int b){ ///ASSERTING A>B if(b==0) return a; return nwd(b, a%b); } int arr[N]; ll lap[N][N]; ll bin_pow(ll a, int b){ ll ans=1; while(b!=0){ if(b & 1) ans*=a; b=b>>1; a=a*a; a=a%M; ans=ans%M; } return ans; } ll inv(int x){ return bin_pow(x, M-2); } ll det(int k){ /// det of lap truncated to range (k, ..., n-1) //cout << k << endl; if(k==n-1) return lap[k][k]; int swp = -1; fors(i, n, k){ swp=i; if(lap[k][i]!=0) break; } fors(i, n, k) swap(lap[i][k], lap[i][swp]); if(swp!=k) lap[k][k]=(M-lap[k][k])%M; ll mult = inv(lap[k][k]); fors(j, n, k+1){ ///iterating by rows ll mult_ = mult*lap[k][j]; mult_=mult_%M; mult_=M-mult_; mult_=mult_%M; fors(i, n, k){ lap[i][j] += lap[i][k]*mult_; lap[i][j]=lap[i][j]%M; } } return (lap[k][k]*det(k+1))%M; } int main() { cin >> n; foru(i, n) cin >> arr[i]; foru(i, n) lap[i][i]=0; foru(i, n) foru(j, n){ if(i==j) continue; ll edges = nwd(max(arr[i], arr[j]), min(arr[i], arr[j])); lap[i][j]=(M-edges)%M; lap[i][i]+=edges; } cout << det(1); return 0; } |