「SDOI2010」外星千足虫 - 线性基 / 高斯消元

nn个未知数x1,x2,...,xnx_1,x_2,...,x_n,给出mm条消息,每条消息选出一些未知数并告诉你他们的和的奇偶性

你的目标是判断每个未知数的奇偶性

如果前kk条消息就可以确定所有未知数的奇偶性,输出kk以及所有未知数的奇偶性,否则输出存在多解

n1000,m2000n\le1000,m\le2000

Luogu P2447

Solution

可以直接高斯消元或者用线性基解异或方程组

线性基做的话,用bitset存,把常数项也压进去,当作一个新的变量跟着一起异或就行了

Code

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
93
94
95
96
97
#include <bits/stdc++.h>

#define x first
#define y second
#define y1 Y1
#define y2 Y2
#define mp make_pair
#define pb push_back

using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

template <typename T> inline int Chkmax (T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline int Chkmin (T &a, T b) { return a > b ? a = b, 1 : 0; }
template <typename T> inline T read ()
{
T sum = 0, fl = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fl = -1;
for (; isdigit(ch); ch = getchar()) sum = (sum << 3) + (sum << 1) + ch - '0';
return sum * fl;
}

inline void proc_status ()
{
ifstream t ("/proc/self/status");
cerr << string (istreambuf_iterator <char> (t), istreambuf_iterator <char> ()) << endl;
}

const int Maxn = 1000 + 100, Maxm = 2000 + 100;

int N, M;

namespace Basis
{
bitset <Maxn> A[Maxm];

inline int insert (bitset <Maxn> x)
{
for (int i = 0; i < N; ++i)
{
if (!x[i]) continue;
if (!A[i].any())
{
for (int j = i + 1; j < N; ++j) if (x[j]) x ^= A[j];
for (int j = 0; j < i; ++j) if (A[j][i]) A[j] ^= x;
A[i] = x;
return 1;
}
x ^= A[i];
}
return 0;
}

inline void query ()
{
for (int i = 0; i < N; ++i) A[i][N] ? puts("?y7M#") : puts("Earth");
}
}

char S[Maxn];
bitset <Maxn> A;

inline void Solve ()
{
int cnt = 0, pos = 0;
for (int i = 1; i <= M; ++i)
{
scanf("%s", S);
for (int j = 0; j < N; ++j) A[j] = S[j] - '0';
int x = read<int>();
A[N] = x;
if (Basis :: insert (A)) ++cnt, pos = i;
}

if (cnt < N) { puts("Cannot Determine"); return ; }

cout<<pos<<endl;
Basis :: query ();
}

inline void Input ()
{
N = read<int>(), M = read<int>();
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("A.in", "r", stdin);
freopen("A.out", "w", stdout);
#endif
Input();
Solve();
return 0;
}
感谢你的赞赏!