zoukankan      html  css  js  c++  java
  • 【洛谷2447】[SDOI2010] 外星千足虫(异或高斯消元)

    点此看题面

    • (n)(01)变量,给定(m)个方程,每个方程给出若干个元素的异或和。
    • 问至少使用前几个方程即可求出所有元素值。
    • (nle10^3,mle2 imes10^3)

    线性基+高斯消元

    显然,能解出所有元素值的充要条件就是有(n)个方程,满足任意一个都无法由其他若干个推得。

    发现这个条件有点眼熟,如果我们把每个方程看作一个(n)位的二进制数,就变成要满足任意一个数都无法由其他若干个异或得到。

    这不就是一个线性基嘛!

    所以我们只要维护一个线性基,当元素个数达到(n)的时候就说明此时可以解出所有元素了。

    由于这时候满足第(i)个方程只有第(isim n)个元素可能有值,因此我们只要执行高斯消元的最后一步操作,从后往前枚举每一个元自之前的方程中消去即可。

    具体实现可以用(bitset)优化复杂度。

    代码:(O(frac{n^3}{32}))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 1000
    using namespace std;
    int n,m,v[N+5];bitset<N+5> s,a[N+5];char st[N+5];
    I void Gauss()//轻量版高斯消元
    {
    	RI i,j;for(i=n;i;--i) for(j=i-1;j;--j) a[j].test(i)&&(a[j]^=a[i],0);//枚举每一个元素从之前的方程中消除
    	for(i=1;i<=n;++i) puts(a[i].test(0)?"?y7M#":"Earth");//输出答案
    }
    int main()
    {
    	RI i,j,x,t=0;for(scanf("%d%d",&n,&m),i=1;i<=m;++i)
    	{
    		for(scanf("%s%d",st+1,&x),s.reset(),x&&(s.set(0),0),j=1;j<=n;++j) st[j]&1&&(s.set(j),0);//转化成二进制数
    		for(j=1;j<=n;++j) if(s.test(j)) {if(a[j].any()) s^=a[j];else {a[j]=s,++t;break;}}//维护线性基
    		if(t==n) return printf("%d
    ",i),Gauss(),0;//元素个数达到n说明能解出所有元素了
    	}return puts("Cannot Determine"),0;//始终无法
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    没有生产管理,只会生产的企业即将被淘汰
    实施一套MES系统需要多少钱?
    MES助力日立电梯提升精细化管理水平
    数据定义
    (CVE-2017-16995)Ubuntu内核提权
    (CVE-2017-7494)Linux Samba远程代码执行
    (CVE-2019-13272)Linux本地提权
    vulnhub 之 dc6
    vulnhub 之 dc 5
    vulnhub 之 dc4
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu2447.html
Copyright © 2011-2022 走看看