[ABC261E] Many Operations 题解
[ABC261E] Many Operations 题解
思路解析
首先可以发现,如果直接按照题目要求跑肯定会炸,于是考虑优化。
考虑预处理,发现操作有很多重复的,所以可以考虑把每一个数经过所有操作后的值都预处理下来,但这样会有 \(2^{30}\) 个数,显然空间也会炸。
然后我们又想可以不需要求 所有的 数经过操作后的值,可以把每个数拆成 \(30\) 个 二进制位 ,然后分别考虑每一个二进制位开始时的情况和对应的结束时的答案。
最后在需要查询时遍历每一位,把每一位上对应二进制的值取出来再相加即可。
还有就是尽量不要用我的代码的实现去写,看上去十分丑陋不便于调试,可以直接用 bitset 或整形变量存储,没必要使用 dp。
code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int n, c;
int f[2][N][32];
signed main() {
cin >> n >> c;
for(int i = 0; i <= 30; i++) f[1][0][i] = 1;
for(int i = 1, op, x; i <= n; i++) {
cin >> op >> x;
for(int j = 0; j <= 30; j++) {
int t = ((x >> j) & 1);
for(int k = 0; k < 2; k++) {
if(op == 1) f[k][i][j] = f[k][i - 1][j] & t;
else if(op == 2) f[k][i][j] = f[k][i - 1][j] | t;
else if(op == 3) f[k][i][j] = f[k][i - 1][j] ^ t;
}
}
int res = 0;
for(int j = 0; j <= 30; j++) {
int t = ((c >> j) & 1);
res += (f[t][i][j] << j);
} c = res;
cout << res << '\n';
}
return 0;
}

浙公网安备 33010602011771号