《P2447 [SDOI2010]外星千足虫》
非常好的一个题。
首先很显然能构造异或方案组。
但是这里n,m都很大,如果用一般的高斯消元肯定会超时。
这时就可以利用bitset来加速整行的消元操作。
然后就是要考虑怎么取找最少的方案组数量了。
这个我们在消元的时候尽量去找前面的消就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef long double ld; typedef pair<int,int> pii; const int N = 1e3 + 5; const int M = 2e3 + 5; const LL Mod = 998244353; #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; inline long long ADD(long long x,long long y) { if(x + y < 0) return ((x + y) % Mod + Mod) % Mod; return (x + y) % Mod; } inline long long MUL(long long x,long long y) { if(x * y < 0) return ((x * y) % Mod + Mod) % Mod; return x * y % Mod; } inline long long DEC(long long x,long long y) { if(x - y < 0) return (x - y + Mod) % Mod; return (x - y) % Mod; } bitset<N> a[M]; int Gauss(int n,int m) {//n个变量,m个方程 int num = -1; for(int i = 1;i <= n;++i) {//消去第i个元 int now = i; while(now <= m && !a[now].test(i)) now++; if(now > m) return 0;//有多组解 num = max(num,now); if(now != i) swap(a[i],a[now]); for(int j = 1;j <= m;++j) { if(i != j && a[j].test(i)) a[j] ^= a[i];//可以消元,进行消元 } } return num; } void solve() { int n,m;scanf("%d %d",&n,&m); for(int i = 1;i <= m;++i) { string s;cin >> s; int x;scanf("%d",&x); for(int j = 1;j <= n;++j) a[i].set(j,s[j - 1] - '0'); a[i].set(0,x); } int pos = Gauss(n,m); if(pos <= 0) printf("Cannot Determine\n"); else { printf("%d\n",pos); for(int i = 1;i <= n;++i) printf("%s\n",a[i].test(0) ? "?y7M#" : "Earth"); } } int main() { //int ca;scanf("%d",&ca); //while(ca--) { solve(); //} system("pause"); return 0; }