移動:自分のブログ
トピック
回答
質問の意味は次のように簡略化されます。0からmまでの数を見つけ、一連の操作の後にこの数が最大になるようにします。
元の数にはサイズの制限があり、取得する数はできるだけ大きくする必要があるため、制限を最大限に活用するには、最初から最後まで少しずつ貪欲になり、元の数が0か1かを判別する必要があります。得られる数を1にできる場合は、最善を尽くして選択すると同時に、元の数の制限を考慮して、元の数をできるだけ小さくします。
各ビットが0または1の場合の操作後の状態を記録する必要があります。すべてがゼロの数値とすべてが1の数値を使用して全体として動作するだけで、最後のビットが取り出されます。
コード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,a0,a1,t,ans,st;
char ch[5];
inline void get_ans()
{
for(int i=30;i>=1;i--) //st是原数
{
int cur=1<<(i-1); //cur只有第i位为1
if(a0&cur) ans+=cur; //优先考虑原数为0
else if(a1&cur&&st+cur<=m) ans+=cur,st+=cur;
} //若得到的数必为0,则原数默认为0
}
int main()
{
scanf("%d%d",&n,&m);
a0=0; a1=(1<<30)-1;
for(int i=1;i<=n;i++)
{
scanf("%s%d",ch,&t);
if(ch[0]=='A') a0&=t,a1&=t;
else if(ch[0]=='O') a0|=t,a1|=t;
else a0^=t,a1^=t;
}
get_ans();
printf("%d\n",ans);
return 0;
}