zoukankan      html  css  js  c++  java
  • [BZOJ1923][SDOI2010]外星千足虫

    bzoj
    luogu

    题意

    给你(m)(n)元异或方程,方程是一个一个给的,问你给到第几个的时候出解,或者是在得到(m)个方程后仍不能确定解。保证方程不会前后矛盾,即不会出现无解。

    sol

    我今天突然发现异或方程组的高斯消元和线性基就是一个东西。
    这道题其实就是问你什么时候你可以得到(n)个线性无关方程。
    所以你可以把每个方程组类似线性基那样插入,每次取异或。
    一旦得到(n)个线性无关方程(而且已经满足下三角全是(0)),就可以直接自下而上回代了。
    复杂度(O(n^3)),写个(bitset)可以优化到(O(frac{n^3}{64}))
    二分答案的那个(log)实际上是不需要的。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<bitset>
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 1005;
    int n,m,ele,sol[N];
    char s[N];
    bitset<N>a[N],tmp;
    int main()
    {
    	n=gi();m=gi();
    	for (int ans=1;ans<=m;++ans)
    	{
    		scanf("%s",s+1);int x=gi();
    		for (int i=1;i<=n;++i) tmp[i]=s[i]-'0';tmp[n+1]=x;
    		for (int i=1;i<=n;++i)
    		{
    			if (!tmp[i]) continue;
    			if (!a[i][i]) {a[i]=tmp;++ele;break;}
    			tmp^=a[i];
    		}
    		if (ele==n)
    		{
    			printf("%d
    ",ans);
    			for (int i=n;i;--i)
    			{
    				sol[i]=a[i][n+1];
    				for (int j=n;j>i;--j)
    					if (a[i][j]) sol[i]^=sol[j];
    			}
    			for (int i=1;i<=n;++i) puts(sol[i]?"?y7M#":"Earth");
    			return 0;
    		}
    	}
    	puts("Cannot Determine");return 0;
    }
    
  • 相关阅读:
    上周热点回顾(3.13.7)
    博客园电子期刊2010年1月刊发布啦
    博客园电子期刊2010年2月刊发布啦
    上周热点回顾(2.222.28)
    Android 专题上线
    聊聊2010年春晚
    上周热点回顾(3.83.14)
    博客园上海俱乐部活动通知(20100320)
    上周热点回顾(2.12.7)
    博客园图灵杯第4届博问大赛(2010.2.27~2010.3.27)
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8783184.html
Copyright © 2011-2022 走看看