zoukankan      html  css  js  c++  java
  • [SDOI2010]外星千足虫 题解 高斯消元+bitset简介

    高斯消元 + bitset 简介:

    高斯消元其实就是以加减消元为核心求唯一解。这道题还是比较裸的,可以快速判断出来。我们将每一只虫子看作一个未知数,这样根据它给出的 m 组方程我们可以高斯消元得出每一只虫子的归属地。如果你还不清楚高斯消元的原理可以移步此处

    如果你只是以为这是一道板子题自信提交,那么恭喜你,你将会获得TLE的好成绩。为什么呢?我们知道高斯消元是 $ n^3 $ 复杂度的,而本题数据范围 $ n leq 1000 $ ,$ m leq 2000 $ ,明显会卡出TLE。

    于是乎,bitset登场了,先介绍一下:

    bitset是一种专门用来储存二进制的数组,使用前要先调用函数库。

    他的每一个元素只占 1 bit空间,你可以将它当作bool类型的高精度。

    他的优点很多,你可将他整体使用,也可单个访问,例如:

    bitset<4> a (string("1001"));
    bitset<4> b (string("0011"));
    //注:bitset后面那对尖括号里的数表示a数组的大小
    a+=b;
    //此时a数组为1100
    a[3]=1;
    a[1]=0;
    //此时a数组为1001
    
    

    你不访问它单个的值是,bitset的运算就像一个普通的整数一样,可以进行与(&)、或(|)、异或(^)、左移(<<)、右移(>>)等操作。同时你还可以对这个数里的任意一位赋值修改。

    这样我们就可以将高斯消元降为二维,将每一个方程用一个bitset维护,在用异或运算进行消元即可。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<bitset>//调用bitset函数库
    
    #define ll long long
    #define db double
    #define inf 0x7fffffff
    
    using namespace std;
    
    bitset<1005> s[2001];
    int n,m,ans,now=1;
    
    inline int qr(){//快读
    	char ch;
    	while((ch=getchar())<'0'||ch>'9');
    	int res=ch^48;
    	while((ch=getchar())>='0'&&ch<='9')
    		res=(res<<1)+(res<<3)+(ch^48);
    	return res;
    }
    
    inline int rd(){
    	char ch;
    	while((ch=getchar())<'0'||ch>'9');
    	return ch^48;//每次只读一个
    }
    
    int main(){
    	//freopen(".in","r",stdin);
    	//freopen(".out","w",stdout);
    	n=qr()+1,m=qr();
    	for(int i=1;i<=m;++i)//读入
    		for(int j=1;j<=n;++j)
    			s[i][j]=rd();
    	for(int i=1;i<n;now=++i){
    		while(!s[now][i]&&now<=m)++now;
    		ans=max(ans,now);//更新 k 值
    		if(now==m+1){
    			printf("Cannot Determine
    ");
    			return 0;
    		} //方程不构成唯一解
    		if(now!=i)swap(s[i],s[now]);
    		for(int j=1;j<=m;j++){
    			if(i==j)continue; //不消自己
    			if(!s[j][i])continue;//不是1就不用消
    			s[j]^=s[i];//用异或消去系数 1
    		}//消去其他方程的系数
    	}
    	printf("%d
    ",ans);
    	for(int i=1;i<n;++i)
    		if(s[i][n])printf("?y7M#
    ");
    		else printf("Earth
    ");
    	return 0;
    }
    

    bitset除了可以整体运算外还有很多功能:

    foo.size()  	返回大小(位数)
    foo.count() 	返回1的个数
    foo.any()   	返回是否有1
    foo.none()  	返回是否没有1
    foo.set()   	全都变成1
    foo.set(p)  	将第p + 1位变成1
    foo.set(p, x)   将第p + 1位变成x
    foo.reset() 	全都变成0
    foo.reset(p)    将第p + 1位变成0
    foo.flip() 	 全都取反
    foo.flip(p) 	将第p + 1位取反
    foo.to_ulong()  返回它转换为unsigned long的结果,如果超出范围则报错
    foo.to_ullong() 返回它转换为unsigned long long的结果,如果超出范围则报错
    foo.to_string() 返回它转换为string的结果
    
    ✐☎博主撰文不易,转载还请注明出处;若对本文有疑,请私信或在下方讨论中提出。O(∩_∩)O谢谢!☏

    ☃〔尽管小伙伴们肯定有千百种方式针对,但博主还是极其非常十分不要脸的把反对键吃掉辣!〕☃

    ✿『$At$ $last$:非常一(hu)本(shuo)正(ba)经(dao)的:博主很笨,请不要欺负他』✿✍

  • 相关阅读:
    克如斯卡尔 P1546
    真正的spfa
    第四课 最小生成树 要点
    关于vscode中nullptr未定义
    cmake学习笔记
    python学习笔记
    (BFS 图的遍历) 2906. kotori和迷宫
    (图论基础题) leetcode 997. Find the Town Judge
    (BFS DFS 并查集) leetcode 547. Friend Circles
    (BFS DFS 图的遍历) leetcode 841. Keys and Rooms
  • 原文地址:https://www.cnblogs.com/812-xiao-wen/p/9872897.html
Copyright © 2011-2022 走看看