首页 > 其他 > 详细

线段树懒标记以及标记永久化的liangzhongshixia

时间:2020-05-30 23:01:05      阅读:77      评论:0      收藏:0      [点我收藏+]

懒标记:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define ls now<<1
#define rs now<<1|1
#define N 100007
using namespace std;
ll n,m,judge,a[N],x,y,z;
ll tree[N*4],lzt[N*4];
ll read()
{
    ll ans=0;
    char ch=getchar(),last= ;
    while(ch>9||ch<0)last=ch,ch=getchar();
    while(ch>=0&&ch<=9)ans=(ans<<3)+(ans<<1)+ch-0,ch=getchar();
    return last==-?-ans:ans;
}
void fix(ll now,ll l,ll r,ll k)
{
    lzt[now]=lzt[now]+k;
    tree[now]=tree[now]+k*(r-l+1);
}
void pushup(ll now){tree[now]=tree[ls]+tree[rs];}
void pushdown(ll now,ll l,ll r)
{
    ll mid=(l+r)>>1;
    fix(ls,l,mid,lzt[now]);
    fix(rs,mid+1,r,lzt[now]);
    lzt[now]=0;
}
void build(ll now,ll l,ll r)
{
    if(l==r)
    {
        tree[now]=a[l];
        return;
    }
    ll mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(now);
}
void update(ll now,ll l,ll r,ll L,ll R,ll k)
{
    if(l>=L&&r<=R)
    {
        tree[now]+=k*(r-l+1);
        lzt[now]+=k;
        return;
    }
    pushdown(now,l,r);
    ll mid=(l+r)>>1;
    if(L<=mid)update(ls,l,mid,L,R,k);
    if(R>mid)update(rs,mid+1,r,L,R,k);
    pushup(now);
}
ll query(ll now,ll l,ll r,ll L,ll R)
{
    ll sumnow=0;
    if(l>=L&&r<=R)return tree[now];
    ll mid=(l+r)>>1;
    pushdown(now,l,r);
    if(L<=mid)sumnow+=query(ls,l,mid,L,R);
    if(R>mid)sumnow+=query(rs,mid+1,r,L,R);
    return sumnow;
}
int main(){
    n=read(),m=read();
    for(ll i=1;i<=n;i++)
        a[i]=read();
    build(1,1,n);
    for(ll i=1;i<=m;i++)
    {
        judge=read();
        if(judge==1)
        {
            x=read(),y=read(),z=read();
            update(1,1,n,x,y,z);
        }
        else
        {
            x=read(),y=read();
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

标记永久化:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define ls now<<1
#define rs now<<1|1
#define N 100007
using namespace std;

ll tree[N*4],lzt[N*4],a[N];
ll n,m;
ll read()
{
    ll ans=0;
    char ch=getchar(),last= ;
    while(ch>9||ch<0)last=ch,ch=getchar();
    while(ch>=0&&ch<=9)ans=(ans<<3)+(ans<<1)+ch-0,ch=getchar();
    return last==-?-ans:ans;
}
void pushup(ll now){tree[now]=tree[ls]+tree[rs];}
void build(ll now,ll l,ll r)
{
    if(l==r)
    {
        tree[now]=a[l];
        return;
    }
    ll mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(now);
}
void update(ll now,ll l,ll r,ll L,ll R,ll k)
{
    tree[now]+=((ll)(min(r,R)-(ll)max(l,L)+1)*k);
    if(l>=L&&r<=R)
    {
        lzt[now]+=k;
        return;
    }
    ll mid=(l+r)>>1;
    if(L<=mid)update(ls,l,mid,L,R,k);
    if(R>mid)update(rs,mid+1,r,L,R,k);
}
ll query(ll now,ll l,ll r,ll L,ll R,ll tag)
{
    if(l>=L&&r<=R)
    {
        return tree[now]+((ll)min(r,R)-(ll)max(l,L)+1)*tag;
    }
    ll mid=(l+r)>>1;
    ll sumnow=0;
    if(L<=mid)sumnow+=query(ls,l,mid,L,R,tag+lzt[now]);
    if(R>mid)sumnow+=query(rs,mid+1,r,L,R,tag+lzt[now]);
    return sumnow;
}
int main(){
    n=read(),m=read();
    for(ll i=1;i<=n;i++)
        a[i]=read();
    build(1,1,n);
    ll b,c,d,judge;
    for(ll i=1;i<=m;i++)
    {
        judge=read();
        if(judge==1)
        {
            b=read(),c=read(),d=read();
            update(1,1,n,b,c,d);
        }
        else
        {
            b=read(),c=read();
            printf("%lld\n",query(1,1,n,b,c,0));
        }
    }
    return 0;
}

 

线段树懒标记以及标记永久化的liangzhongshixia

原文:https://www.cnblogs.com/lbssxz/p/12995121.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!