假设目前有x个火魔法 y个星魔法 显然 y个星魔法让y个权值最大的魔法翻倍就行
但是 有一个情况就是 y个星魔法就是前y大的魔法 这时候 肯定有一个y魔法不能翻倍 根据贪心 我们要去掉最小的y魔法 假如最大的x魔法
用权值线段树维护上述操作即可
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+100;
typedef long long ll;
struct node{
int op,d;
}q[N];
int has[N],tot;
ll sum[N<<2];
int cnt[N<<2],fla[N<<2];
#define mid (l+r>>1)
#define ls id<<1
#define rs ls|1
#define lson ls,l,mid
#define rson rs,mid+1,r
void pushup(int id){
sum[id]=sum[ls]+sum[rs];
fla[id]=fla[ls]+fla[rs];
cnt[id]=cnt[ls]+cnt[rs];
}
void update(int id,int l,int r,int pos,int flaa,int c){
if(l==r){
if(c<0) sum[id]=cnt[id]=fla[id]=0;
else{
sum[id]=has[l];
cnt[id]=1;
fla[id]=flaa;
}
return;
}
if(pos<=mid) update(lson,pos,flaa,c);
else update(rson,pos,flaa,c);
pushup(id);
}
int quefla(int id,int l,int r,int k){
if(l==r){
return fla[id];
}
int ans = 0;
if(k<=cnt[rs]) ans+=quefla(rson,k);
else ans+=quefla(lson,k-cnt[rs])+fla[rs];
return ans;
}
ll quesum(int id,int l,int r,int k){
if(l==r){
return sum[id];
}
ll ans = 0;
if(k<=cnt[rs]) ans+=quesum(rson,k);
else ans+=quesum(lson,k-cnt[rs])+sum[rs];
return ans;
}
int kth(int id,int l,int r,int k){
if(l==r){
return l;
}
if(k<=cnt[rs]) return kth(rson,k);
else return kth(lson,k-cnt[rs]);
}
int main(){
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%d%d",&q[i].op,&q[i].d);
has[++tot]=abs(q[i].d);
}
sort(has+1,has+1+tot);
tot=unique(has+1,has+1+tot)-has-1;
for(int i = 1; i <= n; i++){
int v=lower_bound(has+1,has+1+tot,abs(q[i].d))-has;
if(q[i].d<0) q[i].d=-v;
else q[i].d=v;
}
for(int i = 1; i <= n; i++){
update(1,1,tot,abs(q[i].d),q[i].op,q[i].d);
int sumfla=fla[1];
if(sumfla==0){
printf("%lld\n",sum[1]);
}
else if(sumfla==cnt[1]){
ll ret = 2ll*sum[1];
int k1=kth(1,1,tot,sumfla);
ret-=has[k1];
printf("%lld\n",ret);
}
else{
int qufla=quefla(1,1,tot,sumfla);
if(sumfla==qufla){
ll ret = sum[1]+quesum(1,1,tot,sumfla);
int k1=kth(1,1,tot,sumfla),k2=kth(1,1,tot,sumfla+1);
ret-=has[k1];
ret+=has[k2];
printf("%lld\n",ret);
}else{
printf("%lld\n",sum[1]+quesum(1,1,tot,sumfla));
}
}
}
return 0;
}