1 条题解

  • 0
    @ 2025-3-22 13:58:38

    解题思路

    考虑对于一个 kk 我们怎么做。

    注意到我们可以先把 max 这一维给从小到大排序,然后依次枚举这个 bib_i 并顷定 bib_i 为你选取所有 bib_i 中的最大值,考虑此时如何最优,显然选取 kk 个下标 j1,j2,j3,,jkj_1, j_2, j_3, \dots, j_k 满足 l[1,k], jl[1,i]l \in [1,k], \ j_l \in [1,i]jlj_l 互不相同,i=1kaji\sum_{i=1}^{k} a_{j_i} 的值最大,发现这东西就是 aa 序列前 ii 个数字中的前 kk 大值,可持久化线段树维护即可。

    接下来我们考虑将 kk 从小到大依次做,我们发现给予我们的决策是单调不降的,具体的,若 j1j - 1 这个决策劣于 jj 这个决策,则 jj 这个决策将会永远优于 j1j - 1 这个决策,于是加上决策单调性优化即可,使用分治来维护,时间复杂度 O(nlognlogV)O(n \log n \log V)

    参考代码

    ll n;
    struct node{
        ll x,y;
    }a[200010];
    bool cmp(node x,node y){
        return x.y<y.y;
    }
    ll rt[200010*32],id;
    ll ls[200010*32],rs[200010*32],k;
    ll val[200010*32],S[200010*32];
    void pushup(ll x){
        val[x]=val[ls[x]]+val[rs[x]],
        S[x]=S[ls[x]]+S[rs[x]];
    }
    void upd(ll pre,ll&x,ll l,ll r,ll y)
    {
        if(!x)
            x=++id;
        if(l==r)
        {
            val[x]=val[pre]+y;
            S[x]=S[pre]+1;
            return ;
        }
        if(y<=mid)
            rs[x]=rs[pre],
            upd(ls[pre],ls[x],l,mid,y);
        else
            ls[x]=ls[pre],
            upd(rs[pre],rs[x],mid+1,r,y);
        pushup(x);
    }
    ll query(ll x,ll l,ll r,ll k)
    {
        if(!k)
            return 0;
        if(l==r)
            return k*l;
        if(S[rs[x]]>=k)
            return query(rs[x],mid+1,r,k);
        return val[rs[x]]+query(ls[x],l,mid,k-S[rs[x]]);
    }
    ll ans[200010];
    void sol(ll l,ll r,ll L,ll R) //[l,r] 决策点为 [L,R]
    {
        if(l>r)
            return ;
        ll id=-1,l2=max(L,mid);
        ans[mid]=-9e18;
        forl(i,l2,R)
        {
            ll now=query(rt[i],-1e9,1e9,mid);
            if(now-a[i].y>ans[mid])
                ans[mid]=now-a[i].y,
                id=i;
        }
        sol(l,mid-1,L,id);
        sol(mid+1,r,id,R);
    }
    void _clear(){}
    void solve()
    {
        _clear();
        cin>>n;
        forl(i,1,n)
            cin>>a[i].x>>a[i].y;
        sort(a+1,a+1+n,cmp);
        forl(i,1,n)
            upd(rt[i-1],rt[i],-1e9,1e9,a[i].x);
        sol(1,n,1,n);
        forl(i,1,n)
            cout<<ans[i]<<endl;
    }
    
    • 1

    信息

    ID
    1389
    时间
    3000ms
    内存
    512MiB
    难度
    6
    标签
    (无)
    递交数
    10
    已通过
    2
    上传者