GZEZ "六校NOI集训" Day7
T1
矩阵的秩:高斯约旦消元后非空行数。
记录 \(v[i,j]=0/1\) ,表示第 \(j\) 行是否可以影响第 \(i\) 行的结果。
我们称第 \(i\) 行最左侧的 \(1\) 为其代表元(其实就是线性基相关),记 \(id_j\) 为第\(j\) 列的 \(1\) 所在行数。
然后我们对列依次扫描,如果 \(id_j\) 那一行只有一个 \(1\) ,那么这一列中所有可能修改 \(id_j\) 行的那些行改变,如果不会使空行的变成 \(1\) ,那么就会使秩减少,否则不变。
对于其他情况,秩不可能减少,当能改变空行时,秩会增加,否则不变。
同时发现,所有空行是等价的。
使用 bitset 维护。
#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
const int _ = 2000 + 7;
typedef long long ll;
typedef std::bitset<_> B;
int n, m, a[_][_], rk, nw, id[_]; char c, ans[_][_];
B v[_], b[_], e;
void Init() {
int r = 1;
lep(j, 1, m) {
int i = r;
while (i <= n and !b[i][j]) ++i;
if (i == n + 1) continue;
std::swap(b[i], b[r]), std::swap(v[i], v[r]);
lep(i, 1, n) if (i != r) {
if (b[i][j]) b[i] ^= b[r], v[i] ^= v[r];
}
id[j] = r++;
}
lep(i, 1, n) if (!b[i].count()) e |= v[i];
}
int main() {
scanf("%d%d", & n, & m);
lep(i, 1, n) { lep(j, 1, m) { c = getchar();
while (c != '0' and c != '1') c = getchar();
b[i][j] = (c == '1');
} v[i][i] = 1;
}
Init();
lep(j, 1, m) {
int r = id[j];
if (b[r].count() == 1) {
lep(i, 1, n) if (!e[i] and v[r][i]) ans[i][j] = '-'; else ans[i][j] = '0';
}
else {
lep(i, 1, n) if (e[i])
ans[i][j] = '+'; else ans[i][j] = '0';
}
}
lep(i, 1, n) {
lep(j, 1, m) putchar(ans[i][j]);
puts("");
}
return 0;
}
时间仓促,如有错误欢迎指出,欢迎在评论区讨论,如对您有帮助还请点个推荐、关注支持一下

Day7
浙公网安备 33010602011771号