题意就是有大约1-10000个操作,每次插入或者删除一个数,每次操作后的中位数都要输出
然后思路就比较清晰了, 先把数据都读进来,所有的数存起来离散化,然后再处理每个操作,每次维护树状数组即可,然后如果整个序列有奇数个,就直接二分找最中间的,如果偶数个就找两个数。
这题比较恶心的就是输出了。用cout按理说最好了,但是会超时,用long long的话,除以2的时候判奇数输出.5也会挂,除非转换成double然后%.1f不会挂,这一点很费解啊。当然直接用double转化为字符串是不可能挂的。
保险点用double 吧
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAXN 10005
#define MAXM 1000005
#define INF 1000000000
#define eps 1e-6
using namespace std;
int op[MAXN];
int n, a[MAXN], t[MAXN];
double x[MAXN], num[MAXN];
int lowbit(int x)
{return x & -x;
}
void modify(int x, int v)
{for(int i = x; i <= n; i += lowbit(i))a[i] += v;
}
int getsum(int x)
{int sum = 0;for(int i = x; i > 0; i -= lowbit(i))sum += a[i];return sum;
}
int find(double val, int low, int high)
{while(low <= high){int mid = (low + high) >> 1;if(fabs(x[mid] - val) < eps) return mid;if(x[mid] > val) high = mid - 1;else low = mid + 1;}return -1;
}
int median(int val, int low, int high)
{while(low <= high){int mid = (low + high) >> 1;int sum = getsum(mid);if(sum >= val) high = mid - 1;else low = mid + 1;}return low;
}
void output(double val)
{if(floor(val) == val)printf("%.0f\n", val);else{char s[55];sprintf(s, "%f", val);int len = strlen(s);int pos = len - 1;for(int i = len - 1; i >= 0; i--){if(s[i] != '0' || i == 0){pos = i;break;}}for(int i = 0; i <= pos; i++) putchar(s[i]);putchar('\n');}
}
int main()
{int T;char s[22];scanf("%d", &T);while(T--){scanf("%d", &n);for(int i = 1; i <= n; i++){scanf("%s%lf", s, &num[i]);if(s[0] == 'r') op[i] = 0;else op[i] = 1;x[i] = num[i];}sort(x + 1, x + n + 1);int f = n;n = unique(x + 1, x + n + 1) - x - 1;memset(a, 0, sizeof(a));memset(t, 0, sizeof(t));for(int i = 1; i <= f; i++){if(op[i]){int pos = find(num[i], 1, n);modify(pos, 1);t[pos]++;int len = getsum(n);if(len % 2 == 1){double k = x[median(len / 2 + 1, 1, n)];output(k);}else{double k1 = x[median(len / 2, 1, n)];double k2 = x[median(len / 2 + 1, 1, n)];output((k1 + k2) / 2);}}else{int pos = find(num[i], 1, n);if(t[pos] < 1) printf("Wrong!\n");else{t[pos]--;modify(pos, -1);int len = getsum(n);if(len == 0) printf("Empty!\n");else if(len % 2 == 1){double k = x[median(len / 2 + 1, 1, n)];output(k);}else{double k1 = x[median(len / 2, 1, n)];double k2 = x[median(len / 2 + 1, 1, n)];output((k1 + k2) / 2);}}}}}return 0;
}