Polycarp plays a computer game (yet again). In this game, he fights monsters using magic spells.
There are two types of spells: fire spell of power x x x deals x x x damage to the monster, and lightning spell of power y y y deals y y y damage to the monster and doubles the damage of the next spell Polycarp casts. Each spell can be cast only once per battle, but Polycarp can cast them in any order.
For example, suppose that Polycarp knows three spells: a fire spell of power 5 5 5, a lightning spell of power 1 1 1, and a lightning spell of power 8 8 8. There are 6 6 6 ways to choose the order in which he casts the spells:
Initially, Polycarp knows 0 0 0 spells. His spell set changes n n n times, each time he either learns a new spell or forgets an already known one. After each change, calculate the maximum possible damage Polycarp may deal using the spells he knows.
Input
The first line contains one integer n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) (1≤n≤2⋅10^5) (1≤n≤2⋅105) — the number of changes to the spell set.
Each of the next n n n lines contains two integers t p tp tp and d d d ( 0 ≤ t p i ≤ 1 ; − 1 0 9 ≤ d ≤ 1 0 9 ; d i ≠ 0 ) (0≤tp_i≤1; −10^9≤d≤10^9; d_i≠0) (0≤tpi≤1;−109≤d≤109;di=0) — the description of the change. If t p i tp_i tpi if equal to 0 0 0, then Polycarp learns (or forgets) a fire spell, otherwise he learns (or forgets) a lightning spell.
If d i > 0 d_i>0 di>0, then Polycarp learns a spell of power d i d_i di. Otherwise, Polycarp forgets a spell with power − d i −d_i −di, and it is guaranteed that he knew that spell before the change.
It is guaranteed that the powers of all spells Polycarp knows after each change are different (Polycarp never knows two spells with the same power).
Output
After each change, print the maximum damage Polycarp can deal with his current set of spells.
Example
input
6
1 5
0 10
1 -5
0 5
1 11
0 -10
output
5
25
10
15
36
21
如果当前有闪电咒语 x x x个,火焰咒语 y y y个,那么会有 min ( x , x + y − 1 ) \min(x,x+y-1) min(x,x+y−1)个咒语的伤害会加倍。其中有一个闪电咒语的伤害一定不会被加倍,根据贪心原则,选择除伤害最小的闪电外前 min ( x , x + y − 1 ) \min(x,x+y-1) min(x,x+y−1)个咒语加倍。可以用树状数组+二分来维护。复杂度为 O ( n log 2 n ) O(n\log ^2n) O(nlog2n)。
#include
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector
#define pii pair
#define mii unordered_map
#define msi unordered_map
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<
using namespace std;
inline int qr() {
int f = 0, fu = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')fu = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
const int N = 2e5 + 10;
struct BIT {
ll c[N];
int n;
inline ll get_sum(int k) {
ll ans = 0;
while (k > 0) {
ans += c[k];
k -= lowbit(k);
}
return ans;
}
inline void add(int t, int v) {
while (t <= n) {
c[t] += v;
t += lowbit(t);
}
}
} tr1, tr2;
vi tmp;
map<int, int> num;
int n, m, tot = 0;
int tp[N], d[N];
multiset<int> st;
ll sum;
inline int find(int x) {
int l = 0, r = m;
while (l < r) {
int mid = (l + r) >> 1;
if (tr1.get_sum(mid) >= x)r = mid;
else l = mid + 1;
}
return l;
}
int main() {
n = qr();
tr1.n = n, tr2.n = n;
repi(i, 1, n)tp[i] = qr(), d[i] = qr(), tmp.pb(abs(d[i]));
sort(all(tmp)), tmp.erase(unique(all(tmp)), tmp.end());
m = tmp.size();
repi(i, 0, m - 1)num[tmp[i]] = i + 1;
repi(i, 1, n) {
sum += d[i];
if (tp[i]) {
if (d[i] > 0) {
tot++;
int cmp = *st.begin();
if (st.empty() || d[i] < cmp) {
tr1.add(m - num[cmp] + 1, 1), tr2.add(m - num[cmp] + 1, cmp);
} else {
tr1.add(m - num[d[i]] + 1, 1), tr2.add(m - num[d[i]] + 1, d[i]);
}
st.insert(d[i]);
} else {
d[i] = -d[i];
tot--;
int cmp = *st.begin();
if (d[i] == cmp) {
st.erase(st.begin());
cmp = *st.begin();
tr1.add(m - num[cmp] + 1, -1), tr2.add(m - num[cmp] + 1, -cmp);
} else {
tr1.add(m - num[d[i]] + 1, -1), tr2.add(m - num[d[i]] + 1, -d[i]);
st.erase(st.find(d[i]));
}
}
} else {
if (d[i] > 0) tr1.add(m - num[d[i]] + 1, 1), tr2.add(m - num[d[i]] + 1, d[i]);
else tr1.add(m - num[-d[i]] + 1, -1), tr2.add(m - num[-d[i]] + 1, d[i]);
}
pl(sum + tr2.get_sum(find(tot)));
}
return 0;
}