zoukankan      html  css  js  c++  java
  • bzoj 1798(线段树)

    传送门

    分析:

    因为同时涉及两种区间更新操作,故考虑用两种$lazytag$去打标记。

    而在我们进行区间加和区间乘的时候,我们会发现,因为乘法的优先级较加法的优先级要高,因此,为了方便处理,我们优先选择下放乘法标记。

    同时我们需要注意,在我们下放乘法标记$mul$的时候,如果当前区间存在加法标记$add$,则我们需要在$add$的基础上乘上$mul$

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=100005;
    int mod;
    typedef long long ll;
    struct St{
        int rt,len;
        ll mul,sum,add;
    }tr[maxn<<2];
    int a[maxn];
    void push_up(int rt){
        tr[rt].sum=(tr[rt<<1].sum+tr[rt<<1|1].sum)%mod;
    }
    void push_down(int rt){
        if(tr[rt].mul!=1){
            tr[rt<<1].mul=(tr[rt<<1].mul*tr[rt].mul)%mod;
            tr[rt<<1|1].mul=(tr[rt<<1|1].mul*tr[rt].mul)%mod;
            tr[rt<<1].add=(tr[rt<<1].add*tr[rt].mul)%mod;
            tr[rt<<1|1].add=(tr[rt<<1|1].add*tr[rt].mul)%mod;
            tr[rt<<1].sum=(tr[rt<<1].sum*tr[rt].mul)%mod;
            tr[rt<<1|1].sum=(tr[rt<<1|1].sum*tr[rt].mul)%mod;
            tr[rt].mul=1;
        }
        if(tr[rt].add){
            tr[rt<<1].add=(tr[rt<<1].add+tr[rt].add)%mod;
            tr[rt<<1|1].add=(tr[rt<<1|1].add+tr[rt].add)%mod;
            tr[rt<<1].sum=(tr[rt<<1].sum+tr[rt<<1].len*tr[rt].add%mod)%mod;
            tr[rt<<1|1].sum=(tr[rt<<1|1].sum+tr[rt<<1|1].len*tr[rt].add%mod)%mod;
            tr[rt].add=0;
        }
    }
    void build(int l,int r,int rt){
        tr[rt].len=r-l+1;
        tr[rt].mul=1;
        tr[rt].add=0;
        if(l==r){
            tr[rt].sum=a[l];
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,rt<<1);
        build(mid+1,r,rt<<1|1);
        push_up(rt);
    }
    void update1(int L,int R,int l,int r,int rt,int x){
        if(L<=l&&R>=r){
            tr[rt].sum=tr[rt].sum+x*tr[rt].len%mod;
            tr[rt].add=(tr[rt].add+x)%mod;
            return ;
        }
        push_down(rt);
        int mid=(l+r)>>1;
        if(L<=mid) update1(L,R,l,mid,rt<<1,x);
        if(R>mid)  update1(L,R,mid+1,r,rt<<1|1,x);
        push_up(rt);
    }
    void update2(int L,int R,int l,int r,int rt,int x){
        if(L<=l&&R>=r){
            tr[rt].mul=tr[rt].mul*x%mod;
            tr[rt].add=tr[rt].add*x%mod;
            tr[rt].sum=tr[rt].sum*x%mod;
            return;
        }
        int mid=(l+r)>>1;
        push_down(rt);
        if(L<=mid) update2(L,R,l,mid,rt<<1,x);
        if(R>mid)  update2(L,R,mid+1,r,rt<<1|1,x);
        push_up(rt);
    }
    ll query(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r){
            return tr[rt].sum%mod;
        }
        int mid=(l+r)>>1;
        push_down(rt);
        ll res=0;
        if(L<=mid) res=(query(L,R,l,mid,rt<<1)+res)%mod;
        if(R>mid) res=(query(L,R,mid+1,r,rt<<1|1)+res)%mod;
        return res;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&mod);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        build(1,n,1);
        scanf("%d",&m);
        while(m--){
            int op,l,r,num;
            scanf("%d%d%d",&op,&l,&r);
            if(op==1){
                scanf("%d",&num);
                update2(l,r,1,n,1,num);
            }
            else if(op==2){
                scanf("%d",&num);
                update1(l,r,1,n,1,num);
            }
            else{
                printf("%lld
    ",query(l,r,1,n,1)%mod);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    HDU 1000 A + B Problem
    HDU 3635 Dragon Balls
    HDU 3461 Code Lock
    HDU 1856 More is better
    HDU 1198 Farm Irrigation
    HDU 1325 Is It A Tree?
    HDU 1001 Sum Problem
    HDU 1829 A Bug's Life
    HDU 2610 Sequence one
    HDU 3350 #define is unsafe
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11007130.html
Copyright © 2011-2022 走看看