前言
- 位运算往往涉及到拆位思考,有时候每一位达到最优解汇合到一起就是全区最优解,同时位运算可以缩小量级,把一个很大的数处理成一个不超过64位的01串
题意
- 选择一个不超过m的数,做k次给定的操作
(opt包含OR,XOR,AND),结果最大可能是多少
思路
- 对每一位来说无非0,1两种情况,所以读入opt和t后可以直接拿00……0和11……1去进行上述操作,然后枚举每一位的最优解,如果填零是最优就填零,否则看填一是否是最优并检查填一会不会超过m,最终输出结果。
AC代码
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,ans=0;
int mx=0x7fffffff,mn=0;
pair<string ,int>a[101010];
scanf("%d %d ",&n,&m);
for(int i=0;i<n;i++){
cin>>a[i].first>>a[i].second;
if(a[i].first=="AND"){mx&=a[i].second;mn&=a[i].second;}
else if(a[i].first=="OR"){mx|=a[i].second;mn|=a[i].second;}
else {mx^=a[i].second;mn^=a[i].second;}
}
for(int i=30;i>=0;i--){
if(1&(mn>>i)){ans+=(1<<i);}
else if((1&(mx>>i))&&m>=(1<<i)){
m-=(1<<i);
ans+=(1<<i);
}
}
printf("%d\n",ans);
return 0;
}
tips
- 位运算该加括号的地方加括号,改用1ll的地方用1ll,别瞎开int和long long,尤其别混着开