题目描述
题解
又是开关灯问题…
统计有几种方案,就是统计有多少个自由元x,那么答案
2x
清数组T_T
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<bitset>
#include<cmath>
using namespace std;
#define N 40
int T,n,x,y,cnt;
bitset<N>a[N];int b[N],ans[N];
int st[N],ed[N];
bool flag,link[N][N];
void clear()
{
n=x=y=cnt=flag=0;
memset(st,0,sizeof(st));memset(ed,0,sizeof(ed));memset(link,0,sizeof(link));
memset(b,0,sizeof(st));memset(ans,0,sizeof(ans));
for (int i=1;i<N;++i) a[i].reset();
}
void gauss()
{
for (int i=1;i<=n;++i)
{
if (!a[i][i])
{
int num=i;
for (int j=i+1;j<=n;++j)
if (a[j][i]) {num=j;break;}
if (num==i) continue;
swap(a[i],a[num]);swap(b[i],b[num]);
}
for (int j=i+1;j<=n;++j)
if (a[j][i]) a[j]^=a[i],b[j]^=b[i];
}
for (int i=n;i>=1;--i)
{
if (!a[i][i])
{
if (b[i]) {flag=true;return;}
else ++cnt;
}
ans[i]=b[i];
for (int j=i-1;j>=1;--j)
if (a[j][i]) b[i]^=ans[i];
}
}
int main()
{
scanf("%d",&T);
while (T--)
{
clear();
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d",&st[i]);
for (int i=1;i<=n;++i) scanf("%d",&ed[i]);
while (~scanf("%d%d",&x,&y))
{
if (!x&&!y) break;
link[x][y]=1;
}
for (int i=1;i<=n;++i)
{
for (int j=1;j<=n;++j)
if (link[j][i]||i==j) a[i][j]=1;
if (st[i]^ed[i]) b[i]=1;
}
gauss();
if (flag) puts("Oh,it's impossible~!!");
else printf("%d\n",1<<cnt);
}
}