感觉这个思路非常巧妙啊~
code:
#include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; ll qpow[40]; int main() { // setIO("input"); ll a=0,b=0,re=0; int i,j,n,m; scanf("%d%d",&n,&m); for(i=0;i<40;++i) qpow[i]=1ll<<i, a+=qpow[i]; for(i=1;i<=n;++i) { ll x; char op[5]; scanf("%s%lld",op,&x); if(op[0]=='A') a&=x,b&=x; if(op[0]=='O') a|=x,b|=x; if(op[0]=='X') a^=x,b^=x; } for(i=33;i>=0;--i) { if(b&qpow[i]) re+=qpow[i]; else if(a&qpow[i] && qpow[i]<=1ll*m) re+=qpow[i], m-=(int)qpow[i]; } printf("%lld ",re); return 0; }
线段树版(可以改装改装加个单点修改之类的)
code:
#include <bits/stdc++.h> #define N 100005 #define lson now<<1 #define rson now<<1|1 #define ll unsigned long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,m; struct node { ll f0,f1; node operator+(const node &b)const { node a; a.f0=(~f0&b.f0)|(f0&b.f1); a.f1=(~f1&b.f0)|(f1&b.f1); return a; } }f[N<<2],A[N]; void build(int l,int r,int now) { if(l==r) { f[now]=A[l]; return; } int mid=(l+r)>>1; if(l<=mid) build(l,mid,lson); if(r>mid) build(mid+1,r,rson); f[now]=f[lson]; if(rson) f[now]=f[now]+f[rson]; } int main() { // setIO("input"); int i,j; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) { ll x; char op[5]; scanf("%s%llu",op,&x); if(op[0]=='A') A[i]=(node){0,x}; if(op[0]=='O') A[i]=(node){x,~0}; if(op[0]=='X') A[i]=(node){x,~x}; } build(1,n,1); ll re=0; for(i=32;i>=0;--i) { if(f[1].f0&(1ll<<i)) re+=(1ll<<i); else if((f[1].f1&(1ll<<i)) && (1ll<<i)<=1ll*m) { m-=(int)(1ll<<i); re+=(1ll<<i); } } printf("%lld ",(long long)re); return 0; }