POJ 1830 开关问题

怕不是今天刚会写异或高斯消元。。还是抄的lyd的


思路:异或高斯消元

提交:1次

题解:

若解唯一,答案为1
无解即出现系数矩阵为0,但增广矩阵为1
有自由元即一整行都是0,此时答案为 \(2^{\texttt{自由元的数量}}\)

#include<iostream>
#include<cstdio>
#define ll long long 
#define R register int
using namespace std;
namespace Luitaryi {
inline ll g() { R x=0,f=1;
  register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
  do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
} int T,n,a[30];
inline int Gauss() {
  for(R i=1;i<=n;++i) {
    for(R j=i+1;j<=n;++j) if(a[j]>a[i]) swap(a[i],a[j]);
    if(a[i]==0) return 1<<(n-i+1);//2^(自由元的数量)
    if(a[i]==1) return -1;//增广矩阵是1,然而系数全是0 
    for(R k=n;k;--k) if(a[i]&(1<<k)) {//若从高位看,第k位是有系数的 
      for(R j=1;j<=n;++j) if(i!=j&&a[j]&(1<<k)) //若a[j][k]==1,即可以进行异或运算 
        a[j]^=a[i]; 
      break;
    }
  } return 1;
}
inline void main() {
  T=g(); while(T--) {
    n=g(); for(R i=1;i<=n;++i) a[i]=g();
    for(R i=1,x;i<=n;++i) x=g(),a[i]^=x,a[i]|=1<<i;
    R x,y,ans; while(x=g(),y=g(),x&&y) a[y]|=1<<x;//可以由x传到y 
    ans=Gauss(); if(ans>0) printf("%d\n",ans);
    else puts("Oh,it's impossible~!!");
  }
}
} signed main() {Luitaryi::main(); return 0;}

2019.09.04
65

posted @ 2019-09-04 21:38  LuitaryiJack  阅读(189)  评论(0编辑  收藏  举报