voiddfs(int u){ for (int i = 1; i <= logn; i++) { fa[u][i] = fa[fa[u][i - 1]][i - 1]; } //debugf("fa[%d][%d] = %d, dep[%d] = %d\n", u, 0, fa[u][0], u, dep[u]); for (int i = head[u], v; i; i = e[i].next) { v = e[i].to; if (v == fa[u][0]) continue; dep[v] = dep[u] + 1; fa[v][0] = u; dfs(v); } }
intlca(int a, int b){ int _a = a, _b = b; if (dep[a] < dep[b]) swap(a, b); int c = dep[a] - dep[b]; for (int i = 0; i <= logn; i++) { if (c & (1 << i)) { a = fa[a][i]; } } if (a == b) return a; for (int i = logn; i >= 0; i--) { if (fa[a][i] != fa[b][i]) { a = fa[a][i], b = fa[b][i]; } } return fa[a][0]; }
intdist(int a, int b){ int c = lca(a, b); //debugf("dist(%d, %d) = %d\n", a, b, dep[a] + dep[b] - dep[c] * 2); return dep[a] + dep[b] - dep[c] * 2; }
voidprint_siz(){ #ifdef DEBUG for (int i = 1; i <= n; i++) { if (root[i] == i) { //debugf("subtree[%d].size = %ld\n", i, subtree[i].size()); //debugf("point = %d / %d len = %d\n", s[i], t[i], diam[i]); } } #endif }
voidmerge(int x, int y){ //debugs("-----------------"); //debugf("merge (%d, %d) \n", x, y); int rtx = root[x], rty = root[y]; if (subtree[rtx].size() > subtree[rty].size()) { swap(rtx, rty); swap(x, y); } dep[x] = dep[y] + 1; fa[x][0] = y; dfs(x); addEdge(x, y); addEdge(y, x); for (int x = 0, len = subtree[rtx].size(), u; x < len; x++) { u = subtree[rtx][x]; root[u] = rty; subtree[rty].push_back(u); } subtree[rtx].clear(); int a = s[rtx], b = t[rtx], c = s[rty], d = t[rty]; //debug(a), //debug(b), //debug(c), //debug(d); if (cmax(diam[rty], dist(a, b))) { s[rty] = a, t[rty] = b; } if (cmax(diam[rty], dist(a, c))) { s[rty] = a, t[rty] = c; } if (cmax(diam[rty], dist(a, d))) { s[rty] = a, t[rty] = d; } if (cmax(diam[rty], dist(b, c))) { s[rty] = b, t[rty] = c; } if (cmax(diam[rty], dist(b, d))) { s[rty] = b, t[rty] = d; } if (cmax(diam[rty], dist(c, d))) { s[rty] = c, t[rty] = d; } }
//author: ycp | https://ycpedef.github.io //#pragma GCC diagnostic error "-std=c++11" //#pragma GCC optimize(2) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdarg> #include<bitset> #define debug(x) cerr << #x << " = " << x << endl #define debugf(...) fprintf(stderr, __VA_ARGS__) #define debugs(x) fputs(x"\n", stderr) usingnamespace std; template <classT> boolcmax(T &a, T b){ return b > a ? (a = b, 1) : 0; } template <classT> boolcmin(T &a, T b){ return b < a ? (a = b, 1) : 0; } template <classT> voidread(T &a){ a = 0; char c = getchar(); int f = 0; while (!isdigit(c)) { f ^= c == '-', c = getchar(); } while (isdigit(c)) { a = a * 10 + (c ^ 48), c = getchar(); } a *= f ? -1 : 1; } structFastin { template <classT> Fastin& operator >> (T &x) {read(x); return *this;} } fastin;
#define int long long
constint MAXN = 2010; constint mod = 1e9 + 7;
int n; bitset <MAXN> a[MAXN]; int rk; int dp[MAXN][MAXN];
intgetrank(){ int res = 0; for (int i = 1, j = 1; j <= n; i++, j++) { bool ok = 0; for (int k = i; k <= n; k++) { if (a[k][j]) { ok = 1; swap(a[k], a[i]); break; } } if (!ok) { i--; continue; } res++; for (int k = i + 1; k <= n; k++) { if (a[k][j]) { a[k] ^= a[i]; } } } return res; }
intpower(int a, int b){ int res = 1; while (b) { if (b & 1) { (res *= a) %= mod; } (a *= a) %= mod; b >>= 1; } return res; }
intinv(int x){ returnpower(x, mod - 2); }
signedmain(){ fastin >> n; for (int i = 1, v; i <= n ;i++) { for (int j = 1; j <= n; j++) { fastin >> v; a[i][j] = v; } } rk = getrank(); //debug(rk); dp[0][0] = 1; for (int i = 1; i <= n; i++) { dp[i][0] = dp[i - 1][0]; for (int j = 1; j <= i ;j++) { dp[i][j] = (power(2, j) * dp[i - 1][j] % mod + (power(2, n) - power(2, j - 1) + mod) % mod * dp[i - 1][j - 1] % mod) % mod; //debugf("dp[%lld][%lld] = %lld\n", i, j, dp[i][j]); } } int ans = 0; for (int i = rk; i <= n; i++) { ans = (ans + dp[n][i] * dp[i][rk] % mod * power(2, n * (n - i)) % mod) % mod; } ans = ans * inv(dp[n][rk]) % mod; cout << ans << endl; return0; }