题解 | #起床困难综合症#

起床困难综合症

https://ac.nowcoder.com/acm/problem/17857

思路

按位确定以下,在某一位如果是0,那么经过这些操作之后是0还是1,类似,如果某一位是1的时候也可以这样确定。 那么我们就可以用logn的时间算出某一个数经过这些操作之后的值,但是这里m有点大,我们不能直接枚举。 我们从高位向低位考虑,如果这一位上放0可以变成1,就直接放0,否则看放1是否能变成1并且不会超过m的范围, 这样处理最后就能得到每一位是0还是1啦。

代码

//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;

//int read(){	int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}

int n,m,res;
bool num0[65],num1[65];
string op;

void Solve(){
	cin>>n>>m;
	bitset<40>num0,num1;
	num1.set();
	for(int i=1,x;i<=n;i++){
		cin>>op>>x;
		if(op=="AND"){
			for(int j=0;j<=62;j++){
				num0[j]=num0[j]&((x>>j)&1ll);
				num1[j]=num1[j]&((x>>j)&1ll);
			}
		}else if(op=="OR"){
			for(int j=0;j<=62;j++){
				num0[j]=num0[j]|((x>>j)&1ll);
				num1[j]=num1[j]|((x>>j)&1ll);
			}
		}else if(op=="XOR"){
			for(int j=0;j<=62;j++){
				num0[j]=num0[j]^((x>>j)&1ll);
				num1[j]=num1[j]^((x>>j)&1ll);
			}
		}
	}
//	for(int i=0;i<=4;i++) cout<<i<<" "<<num0[i]<<" "<<num1[i]<<"!!\n";
	int ans=0,now=0;
	for(int i=62;i>=0;i--){
		if(num0[i]||num1[i]){
			if(num0[i]) ans+=(1ll<<i);
			else if(now+(1ll<<i)<=m) now+=(1ll<<i),ans+=(1ll<<i);
		}
	}
	cout<<ans<<"\n";
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
//  freopen("in.cpp","r",stdin);
//  freopen("out.cpp","w",stdout);
	int T=1;
	//cin>>T;
	while(T--){
		Solve();
	}
//	cerr<<clock()*1.0/CLOCKS_PER_SEC<<endl;
	return 0;
}
全部评论

相关推荐

1 1 评论
分享
牛客网
牛客企业服务