感觉这个思路非常巧妙啊~
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\n",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\n",(long long)re);
return 0;
}