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
| #include<bits/stdc++.h>
using namespace std; typedef long long ll; #define endl '\n' const ll MOD = 1e9 + 7; const int MAXN = 1e5 + 5e2; int n, m, bin[MAXN], head[MAXN], cnt, op[MAXN], pow2[MAXN << 1]; ll res, one, zero, dp[MAXN][2]; struct Edge { int to, nxt; ll val; } e[MAXN << 2];
inline int find(int x) { return bin[x] == x ? x : bin[x] = find(bin[x]); }
inline void add(int from, int to, ll val) { e[cnt] = Edge{to, head[from], val}; head[from] = cnt++; e[cnt] = Edge{from, head[to], val}; head[to] = cnt++; }
inline void merge(int u, int v, ll val) { int fu = find(u); int fv = find(v); if (fu != fv) { add(u, v, val); bin[fu] = fv; } }
inline void init() { memset(dp, 0, sizeof(dp)); memset(head, -1, sizeof(head)); cnt = one = zero = 0; }
inline void dfs(int now, int from) { dp[now][op[now]]++; for (int i = head[now]; i != -1; i = e[i].nxt) { int to = e[i].to; if (to == from)continue; dfs(to, now); dp[now][0] += dp[to][0]; dp[now][1] += dp[to][1];
res = ((res + 1LL * dp[to][0] * (one - dp[to][1]) % MOD * e[i].val % MOD) + MOD) % MOD; res = ((res + 1LL * dp[to][1] * (zero - dp[to][0]) % MOD * e[i].val % MOD) + MOD) % MOD; } }
signed main() { ios::sync_with_stdio(false); cin.tie(); cout.tie(); pow2[0] = 1; for (ll i = 1; i < MAXN; i++) { pow2[i] = (pow2[i - 1] << 1) % MOD; } int Case; cin >> Case; while (Case--) { init(); cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> op[i]; if (op[i] & 1) { one++; } else { zero++; } bin[i] = i; } for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; merge(u, v, pow2[i]); } res = 0; dfs(1, -1); cout << res << endl; cout.flush(); } return 0; }
|