Segment tree update interval + range summation template (array realization) Luo Gu p3372, p3373

Template Topic 1: https://www.luogu.org/problemnew/show/P3372

Lazy marked explain: https://www.cnblogs.com/wushengyang/p/11194456.html

This topic just use a lazy mark, regardless of the order.

AC Code:

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const int inf = 0x3f3f3f3f;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
const int N=100005;
#define ls rt<<1
#define rs rt<<1|1
ll a[N],sum[N*4],lazy[N*4];
void push_up(ll rt){
    sum[rt]=sum[ls]+sum[rs]; //更新和
}
void push_down(ll m,ll rt){ //m为总区间长度
    IF (the lazy [RT]) { // If marker is present lazy 
        the lazy [LS] + = the lazy [RT]; // left subtree lazy flag is equal to the value itself of the parent node plus 
        the lazy [RS] + = the lazy [RT] ; 
        SUM [LS] + = the lazy [RT] * (M- (m >> . 1 )); // lazy labeled by number 
        SUM [RS] + = the lazy [RT] * (m >> . 1 ); 
        the lazy [ RT] = 0 ; 
    } 
} 
void Build (LL L, R & lt LL, LL RT) { // achievements of 
    the lazy [RT] = 0 ; // can contribute directly assigned 0 
    IF (L == R & lt) { 
        SUM [RT] = A [L];
         return  ;
    }
    m LL = (L + R & lt) >> . 1 ; 
    Build (L, m, LS); 
    Build (m + . 1 , R & lt, RS); 
    push_up (RT); 
} 
void Update (LL L, R & lt LL, LL C, LL L, LL R & lt, LL RT) { // interval update [l, r], [L , R] represents the total interval 
    IF (L <= L && R & lt> = R & lt) { 
        the lazy [RT] + = C; // update lazy marker 
        sum [RT] + = C * (L-R & lt + . 1 ); // update the node stored sum values 
        return ; 
    } 
    push_down (R & lt -L + . 1 , RT); // all nodes are updated again labeled lazy 
    ll m = (L + R & lt) >> . 1 ; //Half of the total interval
    IF (L <= m) Update (L, m, C, L, R & lt, LS); // Note that recursion is the total interval variable 
    IF (R & lt> m) Update (m + . 1 , R & lt, C, L, R & lt, RS); 
    push_up (RT); 
} 
LL Query (LL L, LL R & lt, LL L, LL R & lt, LL RT) { // [L, R & lt] interval 
    IF (L <= L && R & lt> = R & lt) return SUM [RT]; 
    push_down (R & lt -L + . 1 , RT); 
    LL m = (L + R & lt) >> . 1 ; // total interval of half 
    LL ANS = 0 ;
     IF (L <= m) = + ANS Query (L, m, L, R & lt, LS); // this is the total interval recursive variable 
    IF (R & lt> m) + ANS = Query (m + . 1 , R & lt, L, R & lt, RS);
     return ans;
}
int main(int argc, char * argv[]) 
{
    std::ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,n,1);
    while(m--){
        ll op,x,y,k;
        cin>>op;
        if(op==1){
            cin>>x>>y>>k;
            update(1,n,k,x,y,1);
        }
        if(op==2){
            cin>>x>>y;
            cout<<query(1,n,x,y,1)<<endl;
        }
    }
    return 0;
}

 

Template Topic 2: https://www.luogu.org/problemnew/show/P3373

This question is due to a variety of interval change operation, so there is a relationship between lazy marker, such as if the first words to him seeking the addition of a plus mark lazy, do multiplication, then the previous mark of laziness plus that part also needs to be done once multiplication, so as to complete.

 

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
const int inf = 0x3f3f3f3f;
int dir[8][2]={{1,0},{0,1},{1,1},{1,-1},{-1,1},{-1,-1},{0,-1},{-1,0}};
#define pi acos(-1)
#define ls rt<<1
#define rs rt<<1|1
#define me0(s) memset(s,0,sizeof(s))
#define me1(s) memset(s,1,sizeof(s))
#define mef(s) memset(s,-1,sizeof(s))
#define meinf(s) memset(s,inf,sizeof(s))
const int N=100005;
ll mod;
ll a[N],sum[N*4],lazya[N*4],lazym[N*4]; //lazya存的加的数,lazym存乘
void push_up(int rt){
    sum[rt]=(sum[ls]+sum[rs])%mod;
}
void push_down(ll m,ll rt){
    lazya[ls]=(lazya[rt]+lazya[ls]*lazym[rt])%mod;//乘法的分配率
    lazya[rs]=(lazya[rt]+lazya[rs]*lazym[rt])%mod;
    lazym[ls]=(lazym[rt]*lazym[ls])%mod; //懒惰标记直接乘
    lazym[rs]=(lazym[rt]*lazym[rs])%mod;
    sum[ls]=(lazya[rt]*(m-(m>>1))+sum[ls]*lazym[rt])%mod;
    sum[rs]=(lazya[rt]*(m>>1)+sum[rs]*lazym[rt])%mod;
    lazya[rt]=0;
    lazym[rt]=1;
}
void build(ll l,ll r,ll rt){
    lazym[rt]=1; //初始化乘值
    if(l==r){
        sum[rt]=a[l];
        return ;
    }
    ll m=(l+r)>>1;
    build(l,m,ls);
    build(m+1,r,rs);
    push_up(rt);
}
void update_a(ll L,ll R,ll c,ll l,ll r,ll rt){//做加法
    if(l<=L&&r>=R){
        sum[rt]=(sum[rt]+(R-L+1)*c)%mod;
        lazya[rt]=(c+lazya[rt])%mod;
        return ;
    }
    push_down(R-L+1,rt);
    ll m=(L+R)>>1;
    if(l<=m) update_a(L,m,c,l,r,ls);
    if(r>m) update_a(m+1,R,c,l,r,rs);
    push_up(rt);
}
void update_m(ll L,ll R,ll c,ll l,ll r,ll rt){//做乘法
    if(l<=L&&r>=R){
        sum[rt]=(sum[rt]*c)%mod;
        lazya[rt]=(c*lazya[rt])%mod;
        lazym[rt]=(c*lazym[rt])%mod;
        return ;
    }
    push_down(R-L+1,rt);
    ll m=(L+R)>>1;
    if(l<=m) update_m(L,m,c,l,r,ls);
    if(r>m) update_m(m+1,R,c,l,r,rs);
    push_up(rt);
}
ll query(ll L,ll R,ll l,ll r,ll rt){
    if(l<=L&&r>=R){
        return sum[rt];
    }
    push_down(R-L+1,rt);
    ll m=(L+R)>>1;
    ll ans=0;
    if(l<=m) ans=(ans+query(L,m,l,r,ls))%mod;
    if(r>m) ans=(ans+query(m+1,R,l,r,rs))%mod;
    return ans%mod;
}
int main(int argc, char * argv[]) 
{
    std::ios::sync_with_stdio(false);
    ll n,m,x,y,k,op;
    cin>>n>>m>>mod;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,n,1);
    while(m--){
        cin>>op;
        if(op==1){
            cin>>x>>y>>k;
            update_m(1,n,k,x,y,1);
        }
        if(op==2){
            cin>>x>>y>>k;
            update_a(1,n,k,x,y,1);
        }
        if(op==3){
            cin>>x>>y;
            cout<<query(1,n,x,y,1)<<endl;
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/wushengyang/p/11196119.html