結果
| 問題 |
No.1421 国勢調査 (Hard)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-03-06 10:01:50 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 134 ms / 2,000 ms |
| コード長 | 3,015 bytes |
| コンパイル時間 | 2,295 ms |
| コンパイル使用メモリ | 207,236 KB |
| 最終ジャッジ日時 | 2025-01-19 12:20:33 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 30 |
ソースコード
//二元体での行列
//計算量 簡約化:O(N*M^2/64)
#include <bits/stdc++.h>
using namespace std;
struct io_setup{
io_setup(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout << fixed << setprecision(15);
}
} io_setup;
template<typename T>
struct F2_Matrix{
vector<T> A;
F2_Matrix(int m) : A(m) {}
int height() const {return A.size();}
int width() const {return A.front().size();}
inline const T &operator [] (int k) const {return A[k];}
inline T &operator [] (int k) {return A[k];}
int row_reduction(vector<int> &b){
int m = height(), n = width(), check = 0, rank = 0;
assert(b.size() == m);
for(int j = 0; j < n; j++){
int pivot = check;
for(int i = check; i < m; i++){
if(A[i][j]) pivot = i;
}
swap(A[check], A[pivot]), swap(b[check], b[pivot]);
if(!A[check][j]) continue;
rank++;
for(int i = 0; i < m; i++){
if(i == check || !A[i][j]) continue;
A[i] ^= A[check], b[i] ^= b[check];
}
if(++check == m) break;
}
return rank;
}
int row_reduction(){
vector<int> x(height(), 0);
return row_reduction(x);
}
vector<vector<int>> Gausiann_elimination(vector<int> b){
int m = height(), n = width();
row_reduction(b);
vector<vector<int>> ret;
vector<int> p(m, n);
vector<bool> is_zero(n, true);
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(A[i][j] == 1) {p[i] = j; break;}
}
if(p[i] < n) is_zero[p[i]] = false;
else if(b[i] == 1) return {};
}
vector<int> x(n, 0);
for(int i = 0; i < m; i++){
if(p[i] < n) x[p[i]] = b[i];
}
ret.push_back(x);
for(int j = 0; j < n; j++){
if(!is_zero[j]) continue;
x[j] = 1;
for(int i = 0; i < m; i++){
if(p[i] < n) x[p[i]] ^= A[i][j];
}
ret.push_back(x), x[j] = 0;
}
return ret;
}
};
int main(){
int M, N; cin >> N >> M;
vector<int> Y(M);
vector<vector<int>> B(M);
for(int i = 0; i < M; i++){
int K; cin >> K;
B[i].resize(K);
for(int j = 0; j < K; j++) {cin >> B[i][j]; B[i][j]--;}
cin >> Y[i];
}
using mat = F2_Matrix<bitset<50>>;
vector<int> ret(N, 0);
for(int i = 0; i < 30; i++){
mat A(M);
vector<int> b(M, 0);
for(int j = 0; j < M; j++){
for(auto &e: B[j]) A[j][e] = 1;
b[j] = (Y[j]>>i)&1;
}
vector<vector<int>> ans = A.Gausiann_elimination(b);
if(ans.empty()) {cout << "-1\n"; return 0;}
for(int j = 0; j < N; j++){
if(ans[0][j] == 1) ret[j] |= (1<<i);
}
}
for(int i = 0; i < N; i++) cout << ret[i] << '\n';
}