HDU-Yuna's confusion 树状数组 Or Multiset
比赛的时候竟然没有想到这题可以用树状数组过,由于数字的区间比较小,所以直接开设一个树状数组,定义sum(i) 表示小于i的数的总数。那么判定一个数是否有的条件就是计算sum(i+1) == sum(i) 便可以了,查找第K大的数,也就可以直接二分了。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #define MAXN 100000 using namespace std; int c[MAXN+5]; int lowbit(int x) { return x & -x; } void modify(int x, int val) { for (int i = x; i <= MAXN; i += lowbit(i)) { c[i] += val; } } int sum(int x) { int ret = 0; for (int i = x; i > 0; i -= lowbit(i)) { ret += c[i]; } return ret; } int bsearch(int l, int r, int k) { int mid, ret = -1; while (l <= r) { mid = (l + r) >> 1; // printf("mid = %d, sum() = %d\n", mid, sum(mid)); // getchar(); if (sum(mid) >= k) { ret = mid; r = mid - 1; } else { l = mid + 1; } } return ret; } int main() { int M, x, y, ret; char op[5]; while (scanf("%d", &M) == 1) { memset(c, 0, sizeof (c)); for (int i = 1; i <= M; ++i) { scanf("%s", op); if (op[0] == 'A') { scanf("%d", &x); modify(x, 1); } else if (op[0] == 'D'){ scanf("%d", &x); // printf("%d %d\n", sum(x), sum(x-1)); if (sum(x) == sum(x-1)) { puts("No Elment!"); } else { modify(x, -1); } } else { // query通过二分查找来对付 scanf("%d %d", &x, &y); y += sum(x); ret = bsearch(x+1, MAXN, y); if (ret == -1) { puts("Not Find!"); } else { printf("%d\n", ret); } } } } return 0; }
还有一种做法,就是直接用STL中的multiset.
代码如下:
#include<iostream> #include<algorithm> #include<set> using namespace std; multiset<int> s; multiset<int>::iterator it; int main(){ int Q; while( ~scanf("%d",&Q)){ s.clear(); char ope[10]; int x,k; for(int i = 1; i <= Q; i++){ scanf("%s", ope); if( ope[0] == 'A' ){ scanf("%d",&x); s.insert(x); } else if( ope[0] == 'D' ){ scanf("%d",&x); int cnt = s.count(x); if( cnt == 0 ){ puts("No Elment!"); continue; } s.erase(x); for(int i = 1; i <= cnt-1; i++) s.insert(x); } else { scanf("%d%d",&x,&k); it = s.upper_bound(x); if( it == s.end() ){//|| (it+(k-1) >= s.end() ) ){ puts("Not Find!"); continue; } int i=1; for(; it != s.end() && i < k; i++, it++); if( it == s.end() ){ puts("Not Find!"); continue; } printf("%d\n", *(it) ); } } } }