线段树(fake)模板

应该是区间修改+区间求和=.=

#include<set>
#include<string>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<map>
#include<queue>
#include<algorithm>
#include<stack>
using namespace std;
#define LL long long
#define MAXN 0x3f3f3f3f
#define INF 500007
LL read()
{
    LL x=0,w=1;
    char ch=0;
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return w*x;
}
struct node
{
    LL l,r,lazy,w;
};
node tree[INF*4];//开4倍空间
LL n,q,f,xx,yy,ans,d;
void update(LL k)//更新当前节点
{
    tree[k].w=tree[k<<1].w+tree[k<<1|1].w;
}
void build(int x,int y,int k)//建树
{
    tree[k].l=x;
    tree[k].r=y;
    if(x==y)
    {
        tree[k].w=read();
        return ;
    }
    LL mid=(x+y)>>1;
    build(x,mid,k<<1);
    build(mid+1,y,k<<1|1);
    update(k);
}
void down(LL k)//将该点的lazy标记下推给子节点
{
    tree[k<<1].lazy+=tree[k].lazy;
    tree[k<<1|1].lazy+=tree[k].lazy;
    tree[k<<1].w+=tree[k].lazy*(tree[k<<1].r-tree[k<<1].l+1);
    tree[k<<1|1].w+=tree[k].lazy*(tree[k<<1|1].r-tree[k<<1|1].l+1);
    tree[k].lazy=0;
}
void add(LL x,LL y,LL num,LL k)//区间增加 将[x,y]加上num
{
    if(tree[k].l>=x&&tree[k].r<=y)
    {
        tree[k].w+=num*(tree[k].r-tree[k].l+1);
        tree[k].lazy+=num;
        return ;
    }
    down(k);//下推lazy
    LL mid=(tree[k].l+tree[k].r)>>1;
    if(x<=mid)
    {
        add(x,y,num,k<<1);
    }
    if(y>mid)
    {
        add(x,y,num,k<<1|1);
    }
    update(k);//更新当前节点
}
void oneadd(LL nx,LL num,LL k)//单点增加 将节点nx的值加上num
{
    if(tree[k].l==tree[k].r&&tree[k].l==nx)
    {
        tree[k].w+=num;
        return ;
    }
    LL mid=(tree[k].l+tree[k].r)>>1;
    down(k);//下推lazy
    if(nx<=mid)
        oneadd(nx,num,k<<1);
    else
        oneadd(nx,num,k<<1|1);
    update(k);//更新节点
}
LL getsum(LL x,LL y,LL k)//区间求和 求区间[x,y]的和
{
    LL res=0;
    if(tree[k].l>=x&&tree[k].r<=y)
    {
        res=tree[k].w;
        return res;
    }
    down(k);//下推lazy
    LL mid=(tree[k].l+tree[k].r)>>1;
    if(x<=mid)
        res+=getsum(x,y,k<<1);
    if(y>mid)
        res+=getsum(x,y,k<<1|1);
    return res;
}
int main()
{
    n=read();
    build(1,n,1);
    q=read();
    while(q--)
    {
        f=read();
        xx=read();
        yy=read();
        if(f==1)
        {
            d=read();
            add(xx,yy,d,1);
        }
        else
        {
            ans=getsum(xx,yy,1);
            printf("%lld\n",ans);
        }
        
    }
    //system("pause"); 
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值