由于刚开始我也不会,所以代码大多借鉴了网上题解的做法,多使用位运算解决这个问题。实际上换成取模也是可以的。但是位运算会快一点。
但是位运算代码可读性是真低
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
#define R register
#define LL long long
const int inf = 0x3f3f3f3f;
const int MAXN = (1 << 16) + 10;
inline int read()
{
char a = getchar();
int x = 0, f = 1;
for (; a > ‘9‘ || a < ‘0‘; a = getchar())
if (a == ‘-‘)
f = -1;
for (; a >= ‘0‘ && a <= ‘9‘; a = getchar())
x = x * 10 + a - ‘0‘;
return x * f;
}
int sum;
struct BIT
{
private:
int c[MAXN];
inline int lowbit(int x) { return x & -x; }
public:
inline int ask(int x)
{
int ans = 0;
for (; x; x -= lowbit(x))
ans += c[x];
return ans;
}
inline void update(int x, int y)
{
for (; x < MAXN; x += lowbit(x))
c[x] += y;
}
} bit[16];
map<int, int> mp;
int main()
{
freopen("a.in", "r", stdin);
//freopen(".out","w",stdout);
char ch[10];
int x;
int n = read();
while (n--)
{
scanf("%s", ch);
x = read();
if (ch[0] == ‘A‘)
sum += x;
if (ch[0] == ‘I‘)
{
x -= sum;
mp[x]++;
for (R int i = 0; i < 16; i++)
bit[i].update((x & ((1 << (i + 1)) - 1)) + 1, 1);
}
if (ch[0] == ‘D‘)
{
x -= sum;
int cnt = mp[x];
mp[x] = 0;
for (R int i = 0; i < 16; i++)
bit[i].update((x & ((1 << (i + 1)) - 1)) + 1, -cnt);
}
if (ch[0] == ‘Q‘)
{
int ans = 0;
int l = 1 << x;
int r = (1 << (x + 1)) - 1;
ans += bit[x].ask(min(1 << 16, max(0, r - (sum & ((1 << (x + 1)) - 1)) + 1)));
ans -= bit[x].ask(min(1 << 16, max(0, l - (sum & ((1 << (x + 1)) - 1)))));
l |= (1 << (x + 1));
r |= (1 << (x + 1));
ans += bit[x].ask(min(1 << 16, max(0, r - (sum & ((1 << (x + 1)) - 1)) + 1)));
ans -= bit[x].ask(min(1 << 16, max(0, l - (sum & ((1 << (x + 1)) - 1)))));
printf("%d\n", ans);
}
}
return 0;
}
原文:https://www.cnblogs.com/HN-wrp/p/12853615.html