2022江西省赛K Peach Conference

题目链接:https://ac.nowcoder.com/acm/contest/43898/K

大致做法:
只需要会线段树打懒标记和维护最大最小值,再对线段树懒标记下传操作有一些比较深入的理解即可做本题.1、3操作是简单的区间加和区间求和,没什么问题,主要是2操作.
我们来理解一下2操作对应的性质.我们可以想到一个暴力的做法:对于线段树的每一层一层层递归下去,直到递归到最后一层,也就是只包含一个数的区间,再和 |m| 比较大小并做出相应的更改.但是这样做和暴力跑无本质区别.
我们考虑优化.
那么对于当前遍历的区间假如区间最大值都比 |m| 小的话,那么我们直接打懒标记把当前区间全部修改成0即可.如果当前遍历区间最小值都比 |m| 大的话,那么就只做区间减即可.


#define int long long
#define maxn 200010
int n,q;
struct node{
    int l,r;
    int val,addtag;
    int maxx,minn;
    int clear;
}seg[maxn<<2];
void pushup(int rt)
{
    seg[rt].val=seg[lson].val+seg[rson].val;
    seg[rt].maxx=max(seg[lson].maxx,seg[rson].maxx);
    seg[rt].minn=min(seg[lson].minn,seg[rson].minn);
}
void pushdown(int rt)
{
    if(seg[rt].clear)
    {
        seg[lson].val=seg[lson].minn=seg[lson].maxx=seg[lson].addtag=0;
        seg[lson].clear=1;
        seg[rson].val=seg[rson].minn=seg[rson].maxx=seg[rson].addtag=0;
        seg[rson].clear=1;
        seg[rt].clear=0;
    }
    if(seg[rt].addtag)
    {
        seg[lson].val+=seg[rt].addtag*(seg[lson].r-seg[lson].l+1);
        seg[rson].val+=seg[rt].addtag*(seg[rson].r-seg[rson].l+1);
        seg[lson].maxx+=seg[rt].addtag;
        seg[rson].maxx+=seg[rt].addtag;
        seg[lson].minn+=seg[rt].addtag;
        seg[rson].minn+=seg[rt].addtag;
        seg[lson].addtag+=seg[rt].addtag;
        seg[rson].addtag+=seg[rt].addtag;
        seg[rt].addtag=0;
    }
}
void build(int rt,int l,int r)
{
    seg[rt].l=l;
    seg[rt].r=r;
    if(l==r)
    {
        return ;
    }
    int mid = (l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(rt);
}
void change(int rt,int x,int y,int val)
{
    int l=seg[rt].l;
    int r=seg[rt].r;
    if(x<=l&&r<=y)
    {
        if(seg[rt].minn+val>=0)
        {
            seg[rt].maxx+=val;
            seg[rt].minn+=val;
            seg[rt].val+=val*(seg[rt].r-seg[rt].l+1);
            seg[rt].addtag+=val;
            return ;
        }
        if(seg[rt].maxx+val<=0)
        {
            seg[rt].val=seg[rt].maxx=seg[rt].minn=seg[rt].addtag=0;
            seg[rt].clear=1;
            return ;
        }
    }
    pushdown(rt);
    int mid = (l+r)>>1;
    if(x<=mid)change(lson,x,y,val);
    if(y>mid) change(rson,x,y,val);
    pushup(rt);
}
int query(int rt,int x,int y)
{
    int l=seg[rt].l;
    int r=seg[rt].r;
    if(x<=l&&r<=y)
    {
        return seg[rt].val;
    }
    int mid = (l+r)>>1;
    pushdown(rt);
    int ans=0;
    if(x<=mid) ans+=query(lson,x,y);
    if(y>mid) ans+=query(rson,x,y);
    return ans;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>q;
    build(1,1,n);
    while(q--)
    {
        int op,l,r;
        cin>>op>>l>>r;
        if(op==0)
        {
            cout<<query(1,l,r)<<'\n';
        }
        else 
        {
            change(1,l,r,op);
        }
    }
    return 0;
}
posted @ 2024-06-02 18:33  Captainfly19  阅读(7)  评论(0编辑  收藏  举报