原题传送门
用两个堆维护
较小的那部分用大根堆,较大的那部分用小根堆
每次保证大根堆中数的个数 s 1 s1 s1与小根堆的 s 2 s2 s2相比, s 1 = s 2 或 s 1 = s 2 + 1 s1=s2或s1=s2+1 s1=s2或s1=s2+1
这样每次输出大根堆的根就行了
Code:
#include
using namespace std;
int s1, s2, n;
priority_queue <int> q1;
priority_queue < int, vector <int>, greater <int> > q2;
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
inline int get(){
char c = getchar();
for (; c != 'a' && c != 'm'; c = getchar());
if (c == 'a') return 0; else return 1;
}
void add(int x){
if (x <= q1.top()) q1.push(x), ++s1; else q2.push(x), ++s2;
while (s1 < s2) q1.push(q2.top()), q2.pop(), ++s1, --s2;
while (s1 > s2 + 1) q2.push(q1.top()), q1.pop(), --s1, ++s2;
// printf("%d %d %d %d\n", s1, q1.top(), s2, q2.top());
}
int main(){
n = read();
q1.push(read()), ++s1;
for (int i = 2; i <= n; ++i) add(read());
int T = read();
while (T--) if (get()) printf("%d\n", q1.top()); else add(read());
return 0;
}
发现上面那个方法其实无法维护删数,用树状数组可以解决
但是树状数组必须离线离散化,其实最好的方法是平衡树或者stl,但在联赛范围不需要知道
Code:
#include
#define maxn 200010
using namespace std;
struct node{
int x, val, opt, id;
}a[maxn];
int n, tree[maxn], p, m, val[maxn];
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
inline int get(){
char c = getchar();
for (; c != 'a' && c != 'm'; c = getchar());
if (c == 'a') return 0; else return 1;
}
bool cmp1(node x, node y){ return x.opt == y.opt ? x.val < y.val : x.opt < y.opt; }
bool cmp2(node x, node y){ return x.id < y.id; }
int lowbit(int x){ return x & -x; }
void upd(int x){ for (; x <= p; x += lowbit(x)) ++tree[x]; }
int query(int x){ int s = 0; for (; x; x -= lowbit(x)) s += tree[x]; return s; }
int find(int x){
int l = 1, r = p, ans;
while (l <= r){
int mid = (l + r) >> 1;
// if (query(mid) == x) ans = mid;
if (query(mid) >= x) r = mid - 1, ans = mid; else l = mid + 1;
}
return ans;
}
int main(){
n = read();
for (int i = 1; i <= n; ++i) a[i].opt = 0, a[i].val = read();
m = read();
for (int i = n + 1; i <= n + m; ++i){
a[i].id = i;
a[i].opt = get();
if (!a[i].opt) a[i].val = read();
}
sort(a + 1, a + 1 + n + m, cmp1);
a[0].val = a[1].val - 1;
for (int i = 1; i <= n + m; ++i){
if (a[i].opt) break;
if (a[i].val != a[i - 1].val) ++p;
a[i].x = p, val[p] = a[i].val;
}
sort(a + 1, a + 1 + n + m, cmp2);
int s = 0;
for (int i = 1; i <= n + m; ++i){
// printf("%d %d %d\n", a[i].opt, a[i].x, a[i].val);
if (!a[i].opt) upd(a[i].x), ++s;
else printf("%d\n", val[find((s + 1) >> 1)]);
}
return 0;
}