bzoj 3668 起床困难综合征 (位运算)

题目链接:https://darkbzoj.tk/problem/3668

从高位到低位依次计算,注意什么什么能用 \(1\)
留坑,把之前\(wa\)的码写对

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;

const int maxn = 100010;

int n;ll ans,m;
int a[maxn],op[maxn],bm[40],lowa[maxn],lowans[maxn];
char s[10];

int calc(int p,int x){
	int res = x;
	for(int i=1;i<=n;++i){
		if(op[i] == 1) res = res & ((a[i] >> p) & 1);
		if(op[i] == 2) res = res | ((a[i] >> p) & 1);
		if(op[i] == 3) res = res ^ ((a[i] >> p) & 1); 
	}
	return res;
}

ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }

int main(){
	ans = 0;
	n = read(),m = read();
	
	for(int i=1;i<=n;++i){
		scanf("%s%d",s,&a[i]);
		if(s[0] == 'A') op[i] = 1;
		if(s[0] == 'O') op[i] = 2;
		if(s[0] == 'X') op[i] = 3;
	}

	int val = 0;
	for(int i=30;i>=0;--i){
		int res1 = calc(i,1);
		int res0 = calc(i,0);
		if(val + (1 << i) <= m && res0 < res1){
			val += (1 << i); 
			ans += (res1 << i);
		}else{
			ans += (res0 << i);
		}
	}
	
	printf("%lld\n",ans);

	return 0;
}
posted @ 2020-10-31 20:08  Tartarus_li  阅读(68)  评论(0编辑  收藏  举报