高斯消元板子(方程组+异或方程组)

太菜了……不会高斯消元了

原理不讲了,就是贴俩代码

\(1.\)解方程组

		for(int i=1;i<=n;++i)
		{
			int t=i;
			for(int j=i+1;j<=n;++j)
			{
				if(a[j][i]>a[t][i]) t=j;
			} swap(a[i],a[t]);
			if(fabs(a[i][i])<eps) continue;
			double h=a[i][i];
			for(int j=i;j<=n+1;++j) a[i][j]/=h;
			for(int j=1;j<=n;++j)
			{
				if(j==i) continue;
				double tmp=a[j][i];
				for(int k=1;k<=n+1;++k) a[j][k]-=a[i][k]*tmp;
			}
		}

\(2.\)解异或方程组

这里我们在判断解得个数的时候要注意我们可以把每个自由元的值钦定为\(0 \ or \ 1\)

所以 \(ans=2^{cnt}\) 其中 \(cnt\) 为自由元的个数

这里可能可以状压,但是要是 \(n\) 大就不行了,\(n\) 小也不需要……

		int ans=1;
		for(int i=1;i<=n;++i,++ans)
		{
			int t=ans;
			for(int j=ans+1;j<=n;++j) if(a[j][i]>a[t][i]) t=j;
			for(int j=1;j<=n+1;++j) swap(a[t][j],a[ans][j]);
			if(!a[ans][i]) {ans--;continue;}
			for(int j=ans+1;j<=n;++j) if(!a[j][i]) continue;
			else
			{
				for(int k=i;k<=n+1;++k) a[j][k]^=a[ans][k];
			 } 
		}
		for(int i=ans;i<=n;++i) if(a[i][n+1]) puts("no sol");
		printf("%lld\n",1ll<<(n-ans+1));

题目大概会另建博客,直接找标签即可

猜你喜欢

转载自www.cnblogs.com/yspm/p/12746552.html