BZOJ1923：[Sdoi2010]外星千足虫 （高斯消元+二进制压位）

CODE：

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

const int maxn=2010;
const int maxm=40;
typedef long long LL;

LL a[maxn][maxm];
int ans[maxn];
int n,m;

int Gauss()
{
int k=0;
int R,r=1,c=0;
while ( r<=m && c<n )
{
int x=c/60;
int y=c%60;
R=m+1;
for (int i=r; i<=m; i++)
if (a[i][x]&(1LL<<y))
{
R=i;
break;
}

if (R==m+1) r--;
else
{
k=max(k,R);
for (int i=0; i<=n/60; i++) swap(a[R][i],a[r][i]);
for (int i=r+1; i<=m; i++)
if (a[i][x]&(1LL<<y))
for (int j=0; j<=n/60; j++) a[i][j]^=a[r][j];
}

r++;
c++;
}

if (r<=n) return 0;
int x=n/60;
int y=n%60;
for (int i=n; i>=1; i--)
{
ans[i]=((bool)( a[i][x]&(1LL<<y) ));
for (int j=i; j<n; j++)
ans[i]^=( ((bool)( a[i][j/60]&(1LL<<(j%60)) ))*ans[j+1] );
}
return k;
}

int main()
{
freopen("1923.in","r",stdin);
freopen("1923.out","w",stdout);

scanf("%d%d",&n,&m);
for (int i=1; i<=m; i++)
for (int j=0; j<=n; j++)
{
char c=getchar();
while ( c!='0' && c!='1' ) c=getchar();
int x=c-'0';
int p=j/60;
int q=j%60;
if (x) a[i][p]|=(1LL<<q);
}

int temp=Gauss();
if (!temp) printf("Cannot Determine\n");
else
{
printf("%d\n",temp);
for (int i=1; i<=n; i++)
if (ans[i]) printf("?y7M#\n");
else printf("Earth\n");
}

return 0;
}

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客