Home_W的位运算1

题目链接: 传送门解题思路:这题有两种解题思路,一种就是\(n^2\times m\)的时间复杂度,还有一种就是经过预处理的时间复杂度为\(n^2\)的方法,先说第一种,大家直接按照题目要求的来,一行向量一行向量的进行比较久能AC,没有卡时间,先贴代码:
code:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;const int N = 200;
int mp[N][N];//mp记录的是n个向量
int m,n;bool check(int a,int b) {for(int i = 1;i <= m; ++i) {if(mp[a][i] && mp[b][i])//按照题目要求的进行与,当然你也可以用一个&,return true;    //因为此时的mp记录的是0,1离散值,所以两种判断都行}return false;
}int main()
{int t;while(~scanf("%d",&t)) {while(t--) {scanf("%d%d",&n,&m);for(int i = 1; i <= n; ++i) {for(int j = 1;j <= m; ++j) {scanf("%d",&mp[i][j]);}}int res = 0;for(int i = 1;i < n; ++i) {for(int j = i + 1; j <= n; ++j) {if(check(i,j)) {res ++;}}}printf("%d\n",res);}}return 0;
}

第二种思路就有意思了,我们可以通过向量的这些离散值,把每个向量看成二进制,然后把他还原成一个整数然后再用&进行判断,举个栗子,101B和010B,这两个二进制数,我们要判断他们两个是否有关系,我们可以直接从第一位开始与,一直到最后,我们发现这两个数没有关系,这不正是与运算(&)的运算法则吗,所以我们不需要手动的去从第一位一直比较到最后一位,直接把二进制转为十进制保存,然后\(n^2\)的判断,此时的你一定发现了,向量的维度最大时100的,long long是装不下的,嗯,此时需要一个大数,在这里可以使用C++内置的__int128这个数据类型,他能存储128位(二进制)的整数,但是输入输出需要自己手写,不过此题不用
code:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;const int N = 105;
__int128 key[N];
int mp[N];
int m,n;int main()
{int t;while(~scanf("%d",&t)) {while(t--) {scanf("%d%d",&n,&m);for(int i = 1; i <= n; ++i) {for(int j = 1;j <= m; ++j) {scanf("%d",&mp[j]);}__int128 ans = 0;for(int j = m; j > 0; --j) {//这里进行预处理,把二进制转化为十进制ans += mp[j] * (1 << (m - j));}key[i] = ans;}int res = 0;for(int i = 1;i <= n; ++i) {for(int j = i + 1; j <= n; ++j) {if(key[i] & key[j]) {//O(1)的时间复杂度进行比较res ++;}}}printf("%d\n",res);}}return 0;
}

Home_W的位运算2

题目链接: 传送门解题思路:此题和上题,题目类似,只是数据有所变化,如果直接使用上题暴力解法,会T,再加上我们发现向量的维度只有30,也就是告诉我们,将一个向量转化为2进制用int就能存下,思路参见上题
code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;const int N = 105,M = 35;
bool mp[N][M];
int key[N];
int n,m;int main()
{int t;while(~scanf("%d",&t)) {while(t--) {int ans = 0;scanf("%d%d",&n,&m);for(int i = 1;i <= n; ++i) {for(int j = 1;j <= m; ++j) {scanf("%d",&mp[i][j]);}int ans = 0;for(int j = m; j > 0; --j) {//将向量的二进制转化为十进制ans =ans + mp[i][j] * (1 << (m-j));}key[i] = ans;}for(int i = 1;i <= n; ++i) {for(int j = i + 1; j <= n; ++j) {for(int k = j + 1; k <= n; ++k) {if((key[i] & key[j]) && (key[i] & key[k]) &&(key[j] & key[k])) {ans++;}}}}printf("%d\n",ans);}}return 0;
}

Home_W的位运算3

题目链接: 传送门解题思路:很明显我们会想到先把b的数全都 xor 一遍,然后通过一位一位的比较,对每种情况分类讨论就行,具体请看代码,第二种方法就简单了,有一个数学结论 a^b=c => a = b ^ c我先贴结论写法的code:

#include<bits/stdc++.h>
using namespace std;
#define ll long longll a,b,c;int main()
{int t;while(~scanf("%d",&t)) {while(t--) {scanf("%lld%lld",&b,&c);ll ans = 0;for(int i = 0;i < b; ++i) {scanf("%lld",&a);ans ^= a;}printf("%lld\n",c^ans);}
}return 0;
}

第二种手动模拟的code:

#include<bits/stdc++.h>
using namespace std;
#define ll long longll a,b,c;vector<int> p1,p2,p3;//p1对应的是异或后的b,p2对应的是c,p3对应的是xint main()
{int t;while(~scanf("%d",&t)) {//多组输入while(t--) {scanf("%lld%lld",&b,&c);ll ans = 0;for(int i = 0;i < b; ++i) {scanf("%lld",&a);ans ^= a;}while(ans) {//把b转为二进制int k = ans % 2;p1.push_back(k);ans /= 2;}
//      for(int i = p1.size() - 1; i >= 0; --i) {
//          printf("%d%c",p1[i],i==0?'\n':' ');
//      }
//      puts("---------------------");while(c) {//把c转为二进制int k = c % 2;p2.push_back(k);c /= 2;}
//      for(int i = p2.size() - 1; i >= 0; --i) {
//          printf("%d%c",p2[i],i==0?'\n':' ');
//      }
//      puts("---------------------");for(int i = 0, len = max(p2.size(),p1.size());i < len; ++i) {//类似大数模拟的操作只不过大体分为三类,然后再细分情况if(i + 1 > p1.size()) {if(p2[i] == 1)p3.push_back(1);elsep3.push_back(0);}else if(i + 1 > p2.size()) {if(p1[i] == 1)p3.push_back(1);elsep3.push_back(0);}else {if(p2[i] == 1) {if(p1[i] == 0)p3.push_back(1);elsep3.push_back(0);}else if(p2[i] == 0) {if(p1[i] == 0)p3.push_back(0);elsep3.push_back(1);}}}
//      for(int i = p3.size() - 1; i >= 0; --i) {
//          printf("%d%c",p3[i],i==0?'\n':' ');
//      }
//      puts("---------------------");ll res = 0;for(int i = 0, len = p3.size();i < len; ++i) {res = res + p3[i]*(1<<i);}printf("%lld\n",res);p1.clear();p2.clear();p3.clear();//注意清空操作}
}return 0;
}

小节:通过这三题我还是有很大的收获,比如长见识了a^b=c 可以把b除过去……,还有就是&运算符也有了更深的理解。
updata:

Home_W的位运算4

原题链接:传送门
解题思路:通过第三题我们可以知道异或有个性质即:\(a^b=c => a=c^b\),所以我们通过对序列进行前缀异或处理,然后我们将每次异或的结果,在vis数组里面++,表示的是连续的异或的值,然后我们从左到右对s^pre[i]的值进行加和,最后除2就行,注意这里我们需要将vis[0]初始化为1,因为可能有前缀异或结果就等于s的情况。
Code:

#include<bits/stdc++.h>
using namespace std;const int N = 1000005;
int a[N],b[N],n,q,s;
int vis[N*10];int main()
{scanf("%d",&n);vis[0] = 1;for(int i = 1;i <= n; ++i) {scanf("%d",&a[i]);a[i] ^= a[i-1];vis[a[i]]++;}scanf("%d",&q);while(q--) {scanf("%d",&s);int loc;int ans = 0;for(int i = 0;i <= n; ++i) {loc = s ^ a[i];ans += vis[loc];}printf("%d\n",ans/2);}return 0;
}

Home_W的位运算(位运算+预处理)相关推荐

  1. BMP格式知识之二:16位,24位,32位的BMP图片算法是如何运算的

    BMP格式知识之二:16位,24位,32位的BMP图片算法是如何运算的 原文:http://blog.csdn.net/qq445803843/article/details/46476433 这段代 ...

  2. 常用技巧 —— 位运算 —— 位运算基础

    [与运算] 与运算常用于二进制的取位操作,其用符号 & 表示,相同位的两个数字都为1,则为1,若有一个不为1,则为0. 例如:00101 & 11100 = 00100 其会将两个十进 ...

  3. 使用位运算(与运算)代替%操作

    使用位运算(&与运算)代替%操作 %运算为取余运算 由于我们知道位运算比较高效,在某些情况下,当b为2的n次方时,有如下替换公式: a % b = a & (b-1)(b=2^n) 即 ...

  4. 关于库位“参与MRP运算”与“不参与运算”相互变动的注意事项

        一.现状 因实际业务需求,库存从"不参与MRP运算"调整为"不参与运算",反之亦然. 二.原理 1.库位是否参与MRP运算 设置库位是否参与MRP运算, ...

  5. 设变量n为float类型,m为int类型,则以下能实现将n中的数值保留小数点后两位,第三位进行四舍五人运算的表达式是: A) n=(n*100+0.5)/100.0 B)m=n*100+0.5

    设变量n为float类型,m为int类型,则以下能实现将n中的数值保留小数点后两位,第三位进行四舍五人运算的表达式是: A) n=(n100+0.5)/100.0 B)m=n100+0.5 ,n= m ...

  6. 【FPGA】定点数 数据位宽 运算 位宽截取

    在FPGA中,经常使用定点数表示小数,在进行各种运算时,定点数的位宽会发生变化,并且需要在适当地时候对数据的位宽进行截取. 运算要求和引起的位宽变化 假设存在两个数A.B,假定A位宽为m,小数位宽为a ...

  7. java符号位_java 位运算符号

    <道生一,一生二,二生三,三生万物>出自老子的<道德经>第四十二章.主要讲述了一.二.三这几个数字,并不把一.二.三看作具体的事物和具体数量.它们只是表示"道&quo ...

  8. java用流体加减乘除_任意输入两个数,完成加法、减法、乘法、除法运算!(加减乘除运算分别定义四个方法)_学小易找答案...

    [简答题]编写程序实现菜单设计 [简答题]一层平面图 [简答题]编写一个程序实现大小写字母转换 [简答题]利用循环语句输出一个五行的等腰三角形,如下图 [简答题]编写一个程序实现交换两个变量的数值. ...

  9. 2 计算机组成原理第二章 数据的表示和运算 定点数运算 浮点数运算

    文章目录 1 进制转换 2 定点数表示及其运算 2.1 定点数表示 2.1.1 真值→补码 2.1.2 补码→真值 2.1.3 [XT]补 →[-XT]补 2.1.4 真值.原码.反码.补码转换关系图 ...

最新文章

  1. Mat矩阵基本操作与示例 OpenCV
  2. MySQL安装ODBC驱动出现126错误
  3. 2019全新学习路线图发布
  4. Win10系统下Visio安装失败问题
  5. UI组件之AdapterView及其子类(四)Gallery画廊控件使用
  6. 我对新版CCNP考试的一点想法
  7. Ubuntu20.04配置ip地址
  8. 【转】Ubuntu 16.04 远程桌面
  9. html中如何让图片交错,HTML5/Canvas 光圈交错幻觉
  10. Spring Boot————静态方法如何调用Spring容器中的Bean
  11. Spring :事务使用的注意事项
  12. ASP.NET Core 3.0 实战:构建多版本 API 接口
  13. 【上采样问题】双线性插值的几何中心点重合与align_corners
  14. 信奥中的数学:微积分 高等数学 数学分析
  15. windows 垃圾广告软件清除
  16. 对任意合式公式求真值表以及主析取范式和主合取范式(JAVA)
  17. Portable Batch System
  18. 玩拍七不再怕,判断7的倍数有妙招
  19. Mac 解压缩rar文件
  20. iphone为什么不能连接到服务器未响应,苹果手机(iPhone)连接电脑没反应?(这样就可以解决!)...

热门文章

  1. torch.nn.Conv2d
  2. tensorflow : 队列管理 FIFOQueue amp;amp; RandomShuffleQueue
  3. Luogu P4161 [SCOI2009]游戏 数论+DP
  4. oracle 结构化语言查询 DML DDL DCL
  5. 诡异的json包含bom头
  6. C++实现简单的文本查询
  7. [转载]C#异步调用四大方法详解
  8. 必应拼音输入法与搜狗拼音输入法体验性分析检测
  9. http://blog.seirsoft.com
  10. 如何自己制作一个web项目Tomcat+war包的Docker镜像