bzoj 3668 起床困難綜合徵 (位運算)
阿新 • • 發佈:2020-10-31
題目連結: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; }