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
| #include<bits/stdc++.h> using namespace std; typedef long long LL; const int CN = 110, P = 1e9 + 7, i2 = (P + 1) >> 1; int read(){ int s = 0, ne = 1; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if(c == '-') ne = -1; for(; c >= '0' && c <= '9'; c = getchar()) s = (s << 1) + (s << 3) + c - '0'; return s * ne; } int add(int x, int y) {return x + y >= P ? x + y - P : x + y;} int qp(int a, int b){ int r = 1; for(; b; b >>= 1, a = (LL)a * a % P) if(b & 1) r = (LL)r * a % P; return r; } int inv(int x) {return qp(x, P - 2);} class COMP{ public: int a, b; COMP operator + (const COMP &o) const {COMP r; r.a = add(a, o.a), r.b = add(b, o.b); return r;} COMP operator - (const COMP &o) const {COMP r; r.a = add(a, P - o.a), r.b = add(b, P - o.b); return r;} COMP operator * (const COMP &o) const{ COMP r; r.a = (((LL)a * o.a - (LL)3 * b * o.b) % P + P) % P; r.b = ((LL)a * o.b + (LL)b * o.a) % P; return r; } } a[CN][CN], w[5]; COMP I(int a, int b) {COMP o; o.a = a, o.b = b; return o;} bool extinv(COMP o) {return ((LL)o.a * o.a + (LL)3 * o.b * o.b) % P;} COMP inv(COMP o){ if(o.b) o.b = P - o.b; int t = ((LL)o.a * o.a + (LL)3 * o.b * o.b) % P; t = (t + P) % P, t = inv(t), o.a = (LL)o.a * t % P, o.b = (LL)o.b * t % P; return o; } COMP ne(COMP o) {if(o.a) o.a = P - o.a; if(o.b) o.b = P - o.b; return o;} int n, m, B, X[CN * CN], Y[CN * CN], W[CN * CN], ans; int bit(int x, int i) {while(i) x /= 3, i--; return x % 3;} COMP det(){ COMP res = I(1, 0); for(int i = 1; i < n; i++){ int p = i; while(p < n && !extinv(a[p][i])) p++; if(p >= n) return I(0, 0); if(i ^ p) swap(a[p], a[i]), res = ne(res); for(int j = i + 1; j < n; j++){ COMP t = a[j][i] * inv(a[i][i]); for(int k = i; k < n; k++) a[j][k] = a[j][k] - t * a[i][k]; } res = res * a[i][i]; } return res; } void work(int bi, int pw){ COMP cnt1 = I(0, 0), cnt2 = I(0, 0); for(int i = 0; i < 3; i++){ memset(a, 0, sizeof(a)); for(int j = 1; j <= m; j++){ int u = X[j], v = Y[j], c = bit(W[j], bi); if(c == 0) a[u][v] = a[v][u] = ne(w[0]), a[u][u] = a[u][u] + w[0], a[v][v] = a[v][v] + w[0]; if(c == 1) a[u][v] = a[v][u] = ne(w[i]), a[u][u] = a[u][u] + w[i], a[v][v] = a[v][v] + w[i]; if(c == 2) a[u][v] = a[v][u] = ne(w[i << 1]), a[u][u] = a[u][u] + w[i << 1], a[v][v] = a[v][v] + w[i << 1]; } COMP cur = det(); cnt1 = cnt1 + cur * inv(w[i]), cnt2 = cnt2 + cur * inv(w[i << 1]); } ans = add(ans, add((LL)cnt1.a * pw % P, (LL)2 * cnt2.a * pw % P)); } int main(){ freopen("sum.in", "r", stdin), freopen("sum.out", "w", stdout); n = read(), m = read(), w[0] = I(1, 0), w[1] = I(P - i2, i2), w[2] = w[1] * w[1], w[3] = w[0], w[4] = w[1]; for(int i = 1; i <= m; i++) X[i] = read(), Y[i] = read(), B = max(B, W[i] = read()); for(int k = 0, pw = 1; pw <= B; pw *= 3, k++) work(k, pw); printf("%lld\n", (LL)inv(3) * ans % P); return 0; }
|