题意
中文题.
题目链接
思路及题解
开关之间的关系非常奇怪,我们把本题的模型转化一下.
我们令
a
[
i
]
[
j
]
a[i][j]
a[i][j]表示灯泡
j
j
j的状态是否会随着灯泡
i
i
i的状态改变而改变.
我们会发现,对于第
i
i
i个灯泡来说,都有一个方程,哪些灯泡可以通过它打开和它最后的状态.
因为每一个灯泡都是独立的,而且只有
0
,
1
0,1
0,1两个取值,这就是一个异或方程组,我们算一下它有几个自由元,就有
2
多
少
次
方
2^{多少次方}
2多少次方个解.
如果方程组没有解,显然答案也不可能.
同时因为每一位都是
0
,
1
0,1
0,1,可以将数组的一维压成二进制数.
#include<cstdio> //Ithea Myse Valgulious
#include<algorithm>
#include<cctype>
#include<cstring>
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
int a[99]; // a[]里的每一个元素代表一个异或方程,最低位表示常数项,其他位表示每一个未知数的系数.
int gauss(int n){
int i,j,k;
for (i=1;i<=n;++i){
for (j=i+1;j<=n;++j)
if (a[j]>a[i]) swap(a[i],a[j]);
if (!a[i]) return n-i+1; // 此时从i开始的每一个方程组都无限解,显然自由元有n-i+1个.
if (a[i]==1) return -1; // 此时属于0a+0b+0c=1的情况,无解.
for (k=n;k;--k){
if (a[i]>>k&1){
for (j=1;j<=n;++j)
if (i^j&&(a[j]>>k&1))
a[j]^=a[i];
break;
}
}
}return 0;// 非常正常地消元,显然有唯一解.
}
int main(){
for (int t=read();t--;){
int i,j,k,n=read();
memset(a,0,sizeof a);
for (i=1;i<=n;++i) a[i]=read();
for (i=1;i<=n;++i) a[i]=(a[i]|(1<<i))^read();
for (;i=read(),j=read();) a[j]|=1<<i;
int zxy=gauss(n);
if (~zxy) write(1<<zxy),pl;
else puts("Oh,it's impossible~!!");
}
}
谢谢大家.