[题目链接]
http://codeforces.com/contest/1098/problem/D
[题解]
首先 , 记满足 (sum_{i = 1}^{i - 1}{a_{j}} > 2 * a_{i}) 的 (i) 的个数为 (S)。
不难发现答案的上界是 ((N - S))。
考虑如何取到这个上界 , 不妨每次取出最小的两个元素 (a) 和 (b) , 将 (a) , (b) 分别删除 , 再将 ((a + b)) 插入集合。
如果 (a , b) 合并操作不是 "危险" 的 , 那么必然满足 (b) 没有被合并过。因为如果 (b) 被合并过 , 令 (b = c + d) ((c geq d)) , 那么 (d geq frac{b}{2} > a) , 故 (d) 必然被合并过 , 矛盾。
那么对 ([2^0,2^1),[2^1,2^2),[2^2,2^3),cdots,[2^{29},2^{30})) 分别维护区间和及 (multiset) 即可。
时间复杂度 : (O(NlogN))
[代码]
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i , l , r) for (int i = (l); i < (r); ++i)
LL q , ans , sum[60];
multiset < LL > s[60];
char ch[60];
int main() {
int q; scanf("%d" , &q);
while (q--) {
LL x , bit = 0;
scanf("%s%lld" , ch , &x);
for (bit = 1; (1 << bit) <= x; ++bit); --bit;
if (ch[0] == '+') {
sum[bit] += x;
s[bit].insert(x);
} else {
sum[bit] -= x;
s[bit].erase(s[bit].find(x));
}
LL siz = 0 , ans = 0;
for (int i = 0; i < 30; ++i) {
if (!s[i].size()) continue;
ans += (s[i].size() - ((*s[i].begin()) > 2 * siz));
siz += sum[i];
}
printf("%lld
" , ans);
}
return 0;
}