2022summer-rating2A 位运算
链接:https://ac.nowcoder.com/acm/contest/38284/A
来源:牛客网
You are given a sequence of integers
There are three types of queries:
思路:
直接累加肯定会T(但是比赛时数据太弱居然能过)
正确的方法是对于每一位求前缀和,即统计在 区间内有多少个1
求值时通过前缀和将每一位的数累加起来
比如说 &运算 如果 的某一位是0, 那么怎么操作都是0,如果 的某一位是1,那么这一位上的数字是区间中1的数量
|运算如果 的某一位是1, 那么无论 是0 还是 1 都运算为1,这一位是区间长度,如果 的某一位是0,那么这一位上的数字是区间中1的数量
xor运算如果 的某一位是1, 那么这一位上的数字是区间中0的数量,即为区间长度减区间中1的数量。如果 的某一位是0,那么这一位上的数字是区间中1的数量
本题卡快读
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n, m, s[100005][32];
ll ans = 0;
inline ll read() {
char ch = getchar();
ll x = 0, f = 1;
while (ch < '0' || ch > '9') {
if (ch == '-') f = -f;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
int main () {
ll op, l, r, x;
n = read(), m = read();
for (int i = 1; i <= n; i++) {
ll a;
a = read();
for (int j = 0; j <= 30; j++) {
if (a & (1 << j)) s[i][j] = s[i - 1][j] + 1;
else s[i][j] = s[i - 1][j];
}
}
while (m--) {
ans = 0;
op = read(), l = read(), r = read(), x = read();
if (op == 1) {
for (int i = 0; i <= 30; i++) {
if (x & (1 << i)) ans += (s[r][i] - s[l - 1][i]) * (1 << i);
}
}
else if (op == 2) {
for (int i = 0; i <= 30; i++) {
if (x & (1 << i)) ans += (r - l + 1) * (1 << i);
else ans += (s[r][i] - s[l - 1][i]) * (1 << i);
}
}
else {
for (int i = 0; i <= 30; i++) {
if (x & (1 << i)) ans += (r - l + 1 - s[r][i] + s[l - 1][i]) * (1 << i);
else ans += (s[r][i] - s[l - 1][i]) * (1 << i);
}
}
printf("%lld\n", ans);
}
return 0;
}
本文作者:misasteria
本文链接:https://www.cnblogs.com/misasteria/p/16567122.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步