萌新 10pts 求助大老/kel
查看原帖
萌新 10pts 求助大老/kel
610557
shinzanmonoszm 妹妹楼主2023/7/17 19:04
#include<iostream>
#include<algorithm>
#include<set>
using ll=long long;
using piit=std::pair<ll,int>;
const int sz=3e5+10;
const int inf=0x3fffffff;
struct ST{
    struct node{
        piit min,max,l;
        node operator+(const node &a)const{
            return node{std::min(min,a.min),std::max(max,a.max),std::min(l,a.l)};
        }
    }tree[sz<<2];
    ll lazy[sz<<2];
    void build(int p,int ln,int rn){
        if(ln==rn)return tree[p]=node{{inf,ln},{0,ln},{ln,ln}},void();
        int mid=ln+rn>>1;
        build(p<<1,ln,mid);
        build(p<<1|1,mid+1,rn);
        tree[p]=tree[p<<1]+tree[p<<1|1];
    }
    void pushdown(int p,int ln,int rn){
        if(lazy[p]){
            int mid=ln+rn>>1;
            tree[p<<1].l.first+=lazy[p];
            tree[p<<1|1].l.first+=lazy[p];
            lazy[p<<1]+=lazy[p];
            lazy[p<<1|1]+=lazy[p];
            lazy[p]=0;
        }
    }
    void add(int p,int ln,int rn,int l,int r,int val){
        if(ln>=l&&rn<=r)return tree[p].l.first+=val,lazy[p]+=val,void();
        int mid=ln+rn>>1;
        pushdown(p,ln,rn);
        if(l<=mid)add(p<<1,ln,mid,l,r,val);
        if(r>mid)add(p<<1|1,mid+1,rn,l,r,val);
        tree[p]=tree[p<<1]+tree[p<<1|1];
    }
    void modify(int p,int ln,int rn,int pos,int op,int val){
        if(ln==rn){
            if(op==0)tree[p].min.first=val;
            else tree[p].max.first=val;
            return;
        }
        int mid=ln+rn>>1;
        pushdown(p,ln,rn);
        if(pos<=mid)modify(p<<1,ln,mid,pos,op,val);
        else modify(p<<1|1,mid+1,rn,pos,op,val);
        tree[p]=tree[p<<1]+tree[p<<1|1];
    }
    int getpos(int p,int ln,int rn){
        if(ln==rn)return tree[p].l.first!=0?ln-1:ln;
        int mid=ln+rn>>1;
        pushdown(p,ln,rn);
        if(tree[p<<1|1].l.first>0)return getpos(p<<1,ln,mid);
        else return getpos(p<<1|1,mid+1,rn);
    }
    node query(int p,int ln,int rn,int l,int r){
        if(ln>=l&&rn<=r)return tree[p];
        int mid=ln+rn>>1;
        node res={{inf,inf},{0,0},{inf,inf}};
        pushdown(p,ln,rn);
        if(l<=mid)res=res+query(p<<1,ln,mid,l,r);
        if(r>mid)res=res+query(p<<1|1,mid+1,rn,l,r);
        return res;
    }
}st;
int n,q;
std::multiset<ll>min[sz];
std::multiset<ll,std::greater<ll>>max[sz];
void calc(int t){
    ll u=min[t].empty()?inf:*min[t].begin();
    st.modify(1,1,n,t,0,u);
    u=max[t].empty()?0:*max[t].begin();
    st.modify(1,1,n,t,1,u);
}
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin>>n>>q;
    st.build(1,1,n);
    ll ans=0;
    while(q--){
        std::string op;
        int t,v;
        std::cin>>op>>t>>v;
        if(op=="ADD"){
            piit c=st.query(1,1,n,t,n).l;
            if(c.first>0){
                min[t].insert(v),calc(t);
                st.add(1,1,n,t,n,-1),ans+=v;
            }else{
                piit u=st.query(1,1,n,1,c.second).min;
                if(v>u.first){
                    min[u.second].erase(u.first);
                    max[u.second].insert(u.first),calc(u.second);
                    min[t].insert(v),calc(t),ans+=v-u.first;
                    if(u.second<t)st.add(1,1,n,u.second,t-1,1);
                    else if(t<u.second)st.add(1,1,n,t,u.second-1,-1);
                }else max[t].insert(v),calc(t);
            }
        }else{
            if(max[t].find(v)!=max[t].end()){
                max[t].erase(v),calc(t);
                std::cout<<ans<<"\n";
                continue;
            }
            min[t].erase(v),calc(t),ans-=v,st.add(1,1,n,t,n,1);
            piit u=st.query(1,1,n,st.getpos(1,1,n)+1,n).max;
            if(u.first!=0){
                max[u.second].erase(u.first);
                min[u.second].insert(u.first),calc(u.second);
                st.add(1,1,n,u.second,n,-1),ans+=u.first;
	        }
        }
        std::cout<<ans<<"\n";
    }
    return 0;
}
2023/7/17 19:04
加载中...