巧用位运算。
对于有效true的影响:0->1 , 1->0 ;
无效false的影响:0->0 , 1->1 ;
true ^ 0->1 , true^1->0 ;
false^0->0 , false^1->1 ;
已知结果矩阵,和初始矩阵,和关系矩阵。初始矩阵^(关系矩阵*变元) == 结果矩阵 变换->
变元*(关系矩阵)=初始矩阵^结果矩阵
变元的值域【0,1】。
方程解的个数 1<<变元个数
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int maxn = 50;
int a[maxn][maxn]; // zeng guang
int x[maxn] ; // ans_x
int free_x[maxn] ;
inline int gcd(int a , int b) {
return b == 0 ? a : gcd(b,a%b) ;
/*int t ;
while(b){
t = b ;
b = a%b ;
a = t ;
}
return a;*/
}
inline int lcm(int a ,int b){
return a/gcd(a,b)*b;
}
inline int Abs(int a ){
return a > 0 ? a : -a;
}
void debug(int equ , int var){
for(int i = 0 ; i < equ ; ++i){
for(int j = 0 ;j <= var ; ++j){
cout << a[i][j] << " " ;
}
cout << endl;
}
}
int Gauss(int equ , int var) {
int max_r ;
for(int i = 0 ; i <= var ; ++i){
free_x[i] = false ;
x[i] = 0 ;
}
//cout << equ << " " << var << endl;
int row , col ;
for(row = 0 ,col = 0 ; row < equ && col < var ; ++row , ++col) {
max_r = row ;
for(int i = row+1 ; i < equ ; ++i){ // find the max element in this col
if(Abs(a[max_r][col]) < Abs(a[i][col])) max_r = i;
}
if(max_r != row){
for(int j = col ; j <= var ; ++j){ // change
swap(a[max_r][j],a[row][j]) ;
}
}
if(!a[row][col]) { // 0
row--;
//cout << "123" <<endl;
continue ;
}
//debug(3,3) ;
for(int i = row+1 ; i < equ ; ++i){
if(a[i][col]){// sub a[i][col] -> 0
/*int tmp = lcm(abs(a[i][col]),abs(a[row][col])) ;
int up = tmp/(abs(a[row][col])) ;
int down = tmp/(abs(a[i][col])) ;
//cout << tmp << " " << up << " " << down << endl;
if(a[i][col]*a[row][col]<0) up = -up ;
for(int j = col ; j <= var; ++j){
a[i][j] = a[i][j]*down - a[row][j]*up ;
}*/
for(int j = 0 ; j <= var ; ++j){
a[i][j] ^= a[row][j] ;
}
}
}
//system("pause") ;
}
// col == var , [row,equ) == 皆是0000...an
for(int i = row ; i < equ ; ++i){
if(a[i][col] != 0) {
return -1 ; // no solve
}
}
if(row < var){ //[row , equ -1 ] -> (000.000) have free_x ,at least var - row . cal the x[]
//cout << row << " xxx " << endl;
return var - row ;
}
return 0;
}
int s[maxn] , e[maxn] ;
void init(int var) {
for(int i = 0 ;i < var ; ++i){
cin >> s[i] ;
}
for(int i = 0 ;i < var ;++i){
cin >> e[i] ;
a[i][var] = s[i]^e[i] ;
}
for(int i = 0 ;i < var ; ++i){
for(int j = 0 ;j < var ; ++j){
a[i][j] = i==j?1:0;
}
}
}
int main(){
int t ;
cin >> t ;
while(t--){
int var ;
cin >> var ;
init(var) ;
int i , j ;
while(cin >> i >> j && (i|j)){ // I influence J
a[j-1][i-1] = true ;
}
int flag = Gauss(var,var) ;
if(flag == -1){
cout << "Oh,it's impossible~!!" <<endl;
}
else cout << (1<<flag) <<endl;
}
return 0;
}