##[$HDU$ $2852$ $KiKi's$ $K-Number$](http://acm.hdu.edu.cn/showproblem.php?pid=2852) ### 一、题目大意 给定三种操作: `0 x` 表示把`x`插入容器 ; `1 x` 表示删除一个`x`如果没有`x`则输出 `No Elment!` ; `2 a k` 表示比`a`大的数中的第`k`大的数 如果没有输出`No Find!` ### 二、解题思路 * 树状数组维护元素出现次数(权值)前缀和即可 * 操作$0$即修改 * 操作$1$先查询$x$是否存在,如果存在删除一个即可 * 操作$2$可以用二分逐渐逼近答案 ### 三、二分+树状数组+维护个数 **复杂度:$O(logN * logN)$** ```cpp {.line-numbers} #include #include #include #include typedef long long LL; using namespace std; const int N = 100010; // 树状数组模板 #define lowbit(x) (x & -x) typedef long long LL; int c[N]; void add(int x, int v) { while (x < N) c[x] += v, x += lowbit(x); } LL sum(int x) { LL res = 0; while (x) res += c[x], x -= lowbit(x); return res; } int main() { #ifndef ONLINE_JUDGE freopen("HDU2852.in", "r", stdin); #endif // 加快读入 ios::sync_with_stdio(false), cin.tie(0); int m; while (cin >> m) { memset(c, 0, sizeof c); while (m--) { int op; cin >> op; if (op == 0) { int x; cin >> x; add(x, 1); } else if (op == 1) { int x; cin >> x; if (sum(x) - sum(x - 1) == 0) puts("No Elment!"); else add(x, -1); } else { int a, k; cin >> a >> k; int x = sum(a); if (sum(N - 1) - x < k) // 剩余数量不足K个 puts("Not Find!"); else { int l = 1, r = N - 1; while (l < r) { int mid = (l + r) >> 1; if (sum(mid) - x >= k) r = mid; else l = mid + 1; } printf("%d\n", l); } } } } return 0; } ```