3 条题解
-
3
MXOJ Next Problem 3 Solution
题目
思路
询问离线和双树状数组解法还是太复杂了。
首先,题面的意思就是完全不用考虑糖果的顺序,只考虑每一个糖果种类的数量。
愤怒值的本质,就是分给一个小朋友的糖果数量减去种数。
但是,这种方法前人已经提过了,考虑换一个角度。
给 个小朋友分糖果,本质上相当于最多有 个同种糖果不会对答案产生贡献。
也就是说,令 , 为目前第 种糖果的个数,则所有糖果中最多有 个不对答案做贡献。
将糖果总数减去上述表达式的值即为答案。
解题方法
使用树状数组对 进行维护。
复杂度
时间复杂度
令 。
每次增加、减少、查询时都需要对树状数组进行操作,故单次操作时间复杂度为 。
总时间复杂度 。
空间复杂度
令 。
最多可能有 个糖果,故树状数组的大小为 。
总空间复杂度 。
Code
#include <iostream> using namespace std; const int N = 2e6 + 10; int n, q, op, x; int tr[N], buc[N]; inline void update(int x, int y) { for (; x < N; x += (x & -x)) tr[x] += y; } inline int query(int x) { int res = 0; for (; x; x -= (x & -x)) res += tr[x]; return res; } int main() { scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) { scanf("%d", &x); buc[x]++; update(buc[x], 1); } for (int i = 1; i <= q; i++) { scanf("%d%d", &op, &x); if (op == 3) { printf("%d\n", n - query(x)); continue; } if (op == 1) { buc[x]++, n++; update(buc[x], 1); continue; } update(buc[x], -1); buc[x]--, n--; } }
信息
- ID
- 3
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 465
- 已通过
- 95
- 上传者