#include <iostream> #define MOD 1000000007 using namespace std; long long a,b,c,d,e,f,l,k,p,w,n; long long mat[5000][5000],wej[5000]; long long NWD(long long l1, long long l2){ while (l1&&l2) if (l1<=l2) l2%=l1; else l1%=l2; return l1+l2; } void printMatrix() { for(int row = 0; row < n; ++row) { for(int col = 0; col < n; ++col) { cout << mat[row][col] << " "; } cout << "\n"; } cout << "\n"; } long long det() { long long col,row,del,j; for(col=0; col<n; ++col){ // O(n) obiegow #ifdef DBG cout << "Column: " << col << "\n"; printMatrix(); #endif for(row=col; row<n; ++row){ // worst case to srednio O(n/2) obiegow if(mat[row][col]){ #ifdef DBG cout << "Got non-zero value for row " << row << " and col " << col << "\n"; #endif if (row!=col) { swap(mat[row], mat[col]); #ifdef DBG cout << "(1) Swapping rows " << col << " and " << row << "\n"; printMatrix(); #endif } #ifdef DBG else { cout << "Not swapping rows\n"; } #endif break; } } for(row=col+1; row<n; ++row) // srednio O(n/2) obiegow ??? while(1){ del=mat[row][col]/mat[col][col]; #ifdef DBG cout << "del: " << del << "\n"; #endif for (j = col; j < n; ++j){ // srednio O(n/2) obiegow mat[row][j] -= del * mat[col][j]%MOD; if (mat[row][j]<=-MOD) mat[row][j]+=MOD; if (mat[row][j]>=MOD) mat[row][j]-=MOD; } if (mat[row][col] == 0) break; swap(mat[row], mat[col]); #ifdef DBG cout << "(2) Swapping rows " << col << " and " << row << "\n"; printMatrix(); #endif } } long long ret=1; for(long long i=0; i<n; ++i){ ret=ret*mat[i][i]%MOD; } return abs(ret); } int main(){ scanf("%lld", &n); for (a=0; a<n; ++a){ scanf("%lld", &wej[a]); for (b=0; b<a; ++b){ p=NWD(wej[b], wej[a]); mat[a][b]=mat[b][a]=-p; mat[a][a]+=p; mat[b][b]+=p; } } if (n==1){ printf("1\n"); return 0; } --n; // usuwamy ostatni wiersz i kolumne printf("%lld\n", det()); }
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 | #include <iostream> #define MOD 1000000007 using namespace std; long long a,b,c,d,e,f,l,k,p,w,n; long long mat[5000][5000],wej[5000]; long long NWD(long long l1, long long l2){ while (l1&&l2) if (l1<=l2) l2%=l1; else l1%=l2; return l1+l2; } void printMatrix() { for(int row = 0; row < n; ++row) { for(int col = 0; col < n; ++col) { cout << mat[row][col] << " "; } cout << "\n"; } cout << "\n"; } long long det() { long long col,row,del,j; for(col=0; col<n; ++col){ // O(n) obiegow #ifdef DBG cout << "Column: " << col << "\n"; printMatrix(); #endif for(row=col; row<n; ++row){ // worst case to srednio O(n/2) obiegow if(mat[row][col]){ #ifdef DBG cout << "Got non-zero value for row " << row << " and col " << col << "\n"; #endif if (row!=col) { swap(mat[row], mat[col]); #ifdef DBG cout << "(1) Swapping rows " << col << " and " << row << "\n"; printMatrix(); #endif } #ifdef DBG else { cout << "Not swapping rows\n"; } #endif break; } } for(row=col+1; row<n; ++row) // srednio O(n/2) obiegow ??? while(1){ del=mat[row][col]/mat[col][col]; #ifdef DBG cout << "del: " << del << "\n"; #endif for (j = col; j < n; ++j){ // srednio O(n/2) obiegow mat[row][j] -= del * mat[col][j]%MOD; if (mat[row][j]<=-MOD) mat[row][j]+=MOD; if (mat[row][j]>=MOD) mat[row][j]-=MOD; } if (mat[row][col] == 0) break; swap(mat[row], mat[col]); #ifdef DBG cout << "(2) Swapping rows " << col << " and " << row << "\n"; printMatrix(); #endif } } long long ret=1; for(long long i=0; i<n; ++i){ ret=ret*mat[i][i]%MOD; } return abs(ret); } int main(){ scanf("%lld", &n); for (a=0; a<n; ++a){ scanf("%lld", &wej[a]); for (b=0; b<a; ++b){ p=NWD(wej[b], wej[a]); mat[a][b]=mat[b][a]=-p; mat[a][a]+=p; mat[b][b]+=p; } } if (n==1){ printf("1\n"); return 0; } --n; // usuwamy ostatni wiersz i kolumne printf("%lld\n", det()); } |