【BZOJ】3668 [Noi2014]起床困难综合症 贪心
2017-12-12 20:49
387 查看
题目传送门
题目想法好+1,贪心新技能get。
把初始值二进制拆分,分三种情况讨论:
如果当前位为0,但是经过所有操作后为1,显然这一位为0最优。
不满足情况1,如果当前位为1,经过所有操作后还是1,并且答案加上这一位没有超过m,显然这一位为1最优。证明:∑k−1i=12i=2k−1<2k。
前两种情况都不满足,即这一位不管是0还是1经过所有操作后都是0,那么显然这一位为0更优,因为这样可以为之后可能要取的数空出更大的空间。
时间复杂度O(nlog2m),轻松水过这题。
附上AC代码:
题目想法好+1,贪心新技能get。
把初始值二进制拆分,分三种情况讨论:
如果当前位为0,但是经过所有操作后为1,显然这一位为0最优。
不满足情况1,如果当前位为1,经过所有操作后还是1,并且答案加上这一位没有超过m,显然这一位为1最优。证明:∑k−1i=12i=2k−1<2k。
前两种情况都不满足,即这一位不管是0还是1经过所有操作后都是0,那么显然这一位为0更优,因为这样可以为之后可能要取的数空出更大的空间。
时间复杂度O(nlog2m),轻松水过这题。
附上AC代码:
#include <cstdio> using namespace std; const int N=1e5+10; struct note{ char s[5]; int x; inline int calc(int ret){ switch(s[0]){ case 'A': return ret&x; case 'O': return ret|x; case 'X': return ret^x; } } }a ; int n,m,now,ans; inline int calc(int x){ for (int i=1; i<=n; ++i) x=a[i].calc(x); return x; } int main(void){ scanf("%d%d",&n,&m); for (int i=1; i<=n; ++i) scanf("%s%d",a[i].s,&a[i].x); for (now=1; now<=m; now<<=1); for (now>>=1; now; now>>=1){ if (calc(0)&now) continue; if (ans+now<=m&&calc(now)&now) ans+=now; } return printf("%d\n",calc(ans)),0; }
相关文章推荐
- [BZOJ3668][Noi2014]起床困难综合症(贪心)
- 【贪心】BZOJ3668 [Noi2014]起床困难综合症
- BZOJ 3668 NOI2014 起床困难综合症 贪心
- 【贪心】BZOJ3668-[NOI2014]起床困难综合症
- [BZOJ3668][Noi2014]起床困难综合症 贪心
- BZOJ 3668 NOI2014 起床困难综合症 贪心
- [bzoj3668][Noi2014][起床困难综合症] (按位贪心)
- bzoj3668 [Noi2014] 起床困难综合症 贪心
- 【bzoj3668】【noi 2014】【起床困难综合症】【贪心】
- 【bzoj3668】[Noi2014]起床困难综合症 贪心
- bzoj 3668: [Noi2014]起床困难综合症【贪心】
- BZOJ3668: [Noi2014]起床困难综合症|2进制拆分|贪心
- [NOI2014][BZOJ3668] 起床困难综合症|贪心|进制
- BZOJ3668 [Noi2014]起床困难综合症 【贪心】
- bzoj3668 [Noi2014]起床困难综合症(贪心)
- BZOJ 3668 [Noi2014]起床困难综合症 贪心+位运算
- BZOJ 3668 NOI2014 起床困难综合症 贪心
- BZOJ 3668: [Noi2014]起床困难综合症( 贪心 )
- [BZOJ3668][Noi2014]起床困难综合症(位运算+贪心)
- BZOJ 3668: [Noi2014]起床困难综合症【贪心】