[BZOJ 3668] 起床困难综合症
Link:
Solution:
怎么回事啊,难道好好学贪心就能在NOI上切题了?
位运算相关题型的思路:
由于位运算以位为单位,因此每一位一般都是独立的,分别统计即可
因此对于此题我们对每一位都进行贪心策略:
1、如果该位在$m$之内,只要能最终变为1就计算贡献
2、如果该位已经超过$m$,则只有当能从0变为1时才计算贡献
Code:
#include <bits/stdc++.h> using namespace std; const int MAXN=1e5+10; char op[MAXN][5]; int n,m,k,dat[MAXN],mx,res=0; int solve(int pos,int S) { int ret=S<<pos; for(int i=1;i<=n;i++) if(op[i][0]=='A') ret&=(dat[i]&(1<<pos)); else if(op[i][0]=='X') ret^=(dat[i]&(1<<pos)); else ret|=(dat[i]&(1<<pos)); return ret; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%s%d",op[i],&dat[i]),mx=max(mx,dat[i]); for(k=0;(1<<k)<=m;k++) if(solve(k,1)||solve(k,0)) res+=(1<<k); for(;(1<<k)<=mx;k++) if(solve(k,0)) res+=(1<<k); printf("%d",res); return 0; }