题目链接:点击查看

题目大意:我们需要构造一个初始值start,范围在[0,m],要求使用这个初始值进行k次操作后得到的答案最大,每次操作分为三个类型:

  1. AND x:让当前答案与x进行按位与
  2. OR x:让当前答案与x进行按位或
  3. XOR x:让当前答案与x进行按位异或

现在我们需要构造出这个start,使得经过k次操作后得到的end最大,输出end

题目分析:首先我们肯定不能直接枚举m,然后维护最大值,因为m给到了1e9,单单只是枚举一个m都会超时,就别再提每个m还需要n次操作,暴力的时间复杂度是n*m,都到了1e14,完全不用考虑了

我们需要知道关于位运算的一个主要特点:在二进制表示下不进位

换句话说,每一个数字的二进制都是相互独立的,所以我们可以按位讨论,这样就能在logn的时间复杂度内枚举完m符合情况的状态了,时间复杂度下降为n*logm,最多3e6

现在我们需要讨论一下该怎么按位计算,如果这个题目没有m的约束,那么我们按位从小到大枚举和从大到小枚举都是可以的,但是加了这个约束之后,我们就只能按位从大到小枚举才能获得最优解了,因为如果我们从小到大枚举的话,枚举了其中一个比较小的位置,虽然对答案有贡献,但却占据了小于等于m的这个空间,若后续还有更大的位置可以做出贡献,却被m这个约束卡出去的话,那么此时答案必定不是最优的

再就是讨论一下某个位置该放0或1的情况,因为我们要贪心让end尽可能的大,所以对于某一位置,我们计算一下res1和res0,res1和res0分别是在当前位置放1和放0情况下返回的答案,我们肯定会让end加上两者中较大的一个,如果两者相等的话优先放0,不过别忘了还有m这个约束,因为在放0放1对答案的贡献相同的情况下,放1会占据m的空间,所以放0才是最优解,总结下来在某一位放1还是放0可以分为两种情况:start+res1<=m&&res1>res0满足时放1,否则放0

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;int n,m;struct Node
{char op[5];int val;
}op[N];int cal(int bit,int x)//计算当前bit位,初始值为x的情况下得到的答案
{for(int i=1;i<=n;i++){int temp=op[i].val>>bit&1;if(op[i].op[0]=='A')x&=temp;else if(op[i].op[0]=='O')x|=temp;elsex^=temp;}return x<<bit;
}int main()
{
//  freopen("input.txt","r",stdin);
//    ios::sync_with_stdio(false);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%s%d",op[i].op,&op[i].val);int start=0,end=0;//start:初始攻击力 end:最终攻击力 for(int i=30;i>=0;i--)//枚举每一位,注意要从最高位开始枚举才能达到最优解 {int res1=cal(i,1);//当前第i位为1的情况下运算后得到的结果 int res0=cal(i,0);//当前第i位为0的情况下运算后得到的结果 if(start+res1<=m&&res1>res0)//满足条件,第i位用res1填充{start+=res1;//实时更新start end+=res1;}else//否则用res0填充 end+=res0;}printf("%d\n",end);return 0;
}

CH - 0104 起床困难综合症(位运算+贪心)相关推荐

  1. 【NOI2014】起床困难综合症 位运算+贪心

    这道题先求出0和-1经过处理后的答案 具体看代码吧 #include<cstdio> #include<cstring> #include<algorithm> u ...

  2. BZOJ 3668: [Noi2014]起床困难综合症【二进制+贪心】

    3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec Memory Limit: 512 MB Description 21 世纪,许多人得了一种奇怪的病:起床困难综合症 ...

  3. 起床困难综合征(位运算)

    具体说来,drd 的防御战线由 nn 扇防御门组成.每扇防御门包括一个运算 opop 和一个参数 tt,其中运算一定是 OR,XOR,AND 中的一种,参数则一定为非负整数.如果还未通过防御门时攻击力 ...

  4. [NOI2014] 起床困难综合症

    水题的题解也水...... 原题链接:洛谷 P2114 [NOI2014]起床困难综合症 位运算每一位之间互不干扰. 经过所有门之后每一位不外乎四种结果:一定是0,一定是1,不变或取反. 按位枚举,贪 ...

  5. 起床困难综合症(0x01位运算)

    起床困难综合症 题意 drd 的防御战线由 n 扇防御门组成. 每扇防御门包括一个运算 op 和一个参数 t,其中运算一定是 OR,XOR,AND 中的一种,参数则一定为非负整数. 如果还未通过防御门 ...

  6. 位运算 起床困难综合症

    题目描述 21世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm一直坚持与起床困难综合症作斗争.通过研究相关文献,他找到了该病的发病原因 ...

  7. CH0104 起床困难综合症(位运算典例)

    传送门:起床困难综合症 思路:要知道位运算永远只会改变本位,与其它位泾渭分明.据此,我们不难看出,每个位仅有1.0两种状态,在全部运算后,寻找两种状态的最大结果即可. #include<cstr ...

  8. 位运算——起床困难综合症

    传送门:998. 起床困难综合症 - AcWing题库 思路:因为每一位的操作都是互相独立的,所以从高位到低位枚举范围内的每一位,分别求取0或1的情况的最终答案,该位取1的情况下要保证和已经求出来的前 ...

  9. [BZOJ3668][Noi2014]起床困难综合症 贪心

    3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 2409  Solved: 1360 [Submit][ ...

最新文章

  1. 视觉与机械手标定系统技术解决方案
  2. 13接口登记案例 把对象赋值给接口
  3. python测试开发django-35.xadmin注册表信息
  4. android 之Activity的五种传值方式 (在从当前Activity跳转到目标Activity时的传值方式)
  5. 入门之路:“机器学习初学者”公众号2019年的精选原创文章
  6. 红黑树为什么可以确保没有一条路径会比其他路径长出两倍
  7. laravel引入自定义全局函数
  8. Updating Homebrew... ...长时间卡住的问题
  9. FireFox下表单无法刷新重置问题的分析与解决(转)
  10. SolidWorks2020绘制电脑折叠支架
  11. Win10锁屏之后屏幕自动关闭怎么办
  12. tensorflow学习之二 alexnet vgg resnet目标分类
  13. win7怎么用Win10计算机,win7升至win10的电脑,使用半年多后出现各种系统问题,重装还是升级一周年版?...
  14. Oracle函数——字符函数
  15. 基于raft共识搭建的Fabric1.4网络环境
  16. python 回溯算法总结
  17. 黑果安装步骤(手把手教你如何安装黑苹果)
  18. 广州大学纺织服装学院计算机应用,广州大学纺织服装学院代码是多少
  19. Python 中的Path类
  20. C语言sfr指令,51单片机的指令和sfr汇总.pdf

热门文章

  1. springboot整合JWT使用
  2. Nacos源码集群一致性
  3. 抽象工厂产品等级结构与产品族
  4. SpringMVC简介-SpringMVC概述
  5. 特性总览:核心特性、数据存储、Web技术、框架整合与测试
  6. 数据库-聚合函数-max函数
  7. Date类的构造方法和成员方法
  8. 【Homework】银行存取款业务
  9. CSS中的position定位
  10. [译文] 初学者应该了解的数据结构: Tree