题目大意:给出n个开关的初始状态以及目标状态,按下一个开关会相应改变其它某些开关的状态(包括自己),问有多少种方案达到目标状态(每个开关最多按一次)。
这道题目是高斯消元求自由变元的模板题。
首先我们可以列出每个开关i的方程,(A1*t1+A2*t2+A3*t3...+An*tn) mod 2=Bi
其中当改变了第j个开关也会改变第i个开关的状态时,Aj=1,否则=0。当第i个开关的初始状态等于结束状态时,Bi=0,否则=1。
ti表示第i个开关最后有没有按,作为方程中的变量。
我们只要求解出这n个方程的自由变元数量t,答案就是2^t了。
自由变元并不是指值不确定的变量数,而是指不确定的“联通块”数。
比如x+y=2,这个时候自由变元只有1个,因为x和y是互相联系的,属于一个“联通块”,只要确定了其中一个,就可以确定另一个。
再比如x+y+z=2,自由变元就有2个。
我是这样求自由变元数的:
一开始和高斯消元步骤一样。但是往回代的时候需要判断一些东西:
如果当前需要求解的这个变量的系数为0,那么有可能增加自由变元,也有可能无解;
否则这个变量就不可能增加自由变元,虽然它可以是任意值,但是它可以由其它自由变量推出,并没有增加方案数。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <