原题传送门
此题的思想还是位运算&状压DP
位运算的特点是二进制下不进位,故参与位运算的各位之间是相互独立的
X0的第k位应该填为1仅当在下面两种情况时出现:
- 已有数值+1<<k不超过m
- 用每个参数的第k位参与运算,若初值为1,那么经过n次操作后结果为1,0时同理
这样,我们就可以用类似于贪心的思想,得到尽可能大的结果
直接大力设结果,爆算每一位。。
Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 100010;
int n, m, x;
pair<string, int> a[maxn];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = (ch == '-') ? -1 : 1, ch = getchar();
while (isdigit(ch))
x = x * 10 + (ch - '0'), ch = getchar();
return x * f;
}
inline int cal(int bit, int now)
{
for (int i = 1; i <= n; i++)
{
int x = a[i].second >> bit & 1;
if (a[i].first == "AND")
now &= x;
else if (a[i].first == "OR")
now |= x;
else
now ^= x;
}
return now;
}
signed main()
{
n = read(), m = read();
for (int i = 1; i <= n; i++)
{
char str[5];
int x;
scanf("%s%d", str, &x);
a[i] = make_pair(str, x);
}
int val = 0, ans = 0;
for (int bit = 29; bit >= 0; bit--)
{
int res0 = cal(bit, 0);
int res1 = cal(bit, 1);
if (val + (1 << bit) <= m && res0 < res1)
val += 1 << bit, ans += res1 << bit;
else
ans += res0 << bit;
}
cout << ans << '\n';
}