[ABC379D] Home Garden 题解

[ABC379D] Home Garden 题解

题目大意:

实现一个数据结构,使其支持以下三个操作:

1 向这个数据结构中插入一个数值为 \(0\) 的节点。

2 T 将这个数据结构中的所有元素加 \(T\)

3 H 将这个数据结构中大于等与 \(H\) 的元素删除并输出删除的元素数。

思路分析:

由于不存在使此结构中的元素变小的手段,所以集合中的元素按加入时间来排序,其的值是单调不减的。因为存在单调性,则 \(3\) 操作简化为二分查找第一个小于 \(H\) 的元素。

那么如何解决 \(2\) 操作与删除操作呢?

对于操作 \(2\) ,维护一个现时间 \(nt\) ,对于每一个新加入的节点,维护其时间戳 \(t_i\) ,则其的大小为 \(nt-t_i\)

删除操作,由于区间具有单调性,在删除时一定是从左往右删除,则实际不用真的删除,只需维护已经删除的点数量 \(nl\) ,每次二分查找时,使区间左端点等于 \(nl\) 即可。

代码详解:

#include <bits/stdc++.h>
#define seq(q, w, e) for (int q = w; q <= e; q++)
#define int long long
using namespace std;
const int maxn = 2e5+10,inf=0x7fffffff;
int t[maxn];
int nt,sum,nl,h;
int q,op,tot;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin>>q;
    while(q--){
        cin>>op;
        if(op==1){
            tot++;
            t[tot]=nt;
        }
        if(op==2){
            cin>>sum;
            nt+=sum;
        }
        if(op==3){
            cin>>h;
            int l=nl,r=tot+1,mid;
            while(l+1<r){
                mid=(l+r)>>1;
                if((nt-t[mid])>=h){
                    l=mid;
                }
                else{
                    r=mid;
                }
            }
            cout<<l-nl<<"\n";
            nl=l;
        }
    }
    return 0;
}
posted @ 2024-11-10 11:03  adsd45666  阅读(2)  评论(1编辑  收藏  举报