首页 > 其他分享 >线段树模板【带懒标记】

线段树模板【带懒标记】

时间:2022-08-16 16:37:25浏览次数:66  
标签:带懒 int 线段 tr mid cin add sum 模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int a[N];
struct node{
    int l, r;
    ll add, sum;
    node(){
        add = sum = 0;
    }
}tr[N << 2];
void pushup(int u)
{
    tr[u].sum  = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void pushdown(int u)
{
    if(tr[u].add)
    {
        tr[u << 1].sum += tr[u].add * (ll)(tr[u << 1].r - tr[u << 1].l + 1);
        tr[u << 1 | 1].sum += tr[u].add * (ll)(tr[u << 1 | 1].r - tr[ u << 1 | 1].l +1);
        tr[u << 1].add += tr[u].add;
        tr[u << 1 | 1].add += tr[u].add;
        tr[u].add = 0;
    }
}
void build(int u, int l, int r)
{
    tr[u].l = l,tr[u].r = r;
    if(l == r){
        tr[u].sum = a[r];
        return ;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
}
void modify(int u, int x, int l, int r)
{
    if(tr[u].l>=l && tr[u].r <= r)
    {
        tr[u].sum += (ll)(tr[u].r - tr[u].l + 1) * x;
        tr[u].add += x;
        return ;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(mid >= l)
        modify(u << 1, x, l, r);
    if(mid < r)
        modify(u << 1 | 1, x, l, r);
    pushup(u);
}
ll query(int u, int l, int r)
{
    if(tr[u].l>=l && tr[u].r <=r)
        return tr[u].sum;
    //为什么要pushdown:如果tr[u].add > 0 ,那么说明u的子节点还没有更新过
    //pushdown能往下更新一层
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    ll sum = 0;
    if(mid >= l)
        sum = query(u << 1, l, r);
    if(mid < r)
        sum += query(u << 1 | 1, l, r);
    return sum;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    build(1, 1, n);
    while(m--)
    {
        char op[2];
        cin >> op;
        if(op[0] == 'C')
        {
            int l, r, d;
            cin >> l >> r >>d;
            modify(1, d, l, r);
        }
        else{
            int l, r;
            cin >> l >> r;
            cout << query(1, l, r) << endl;
        }
    }
    return 0;
}

标签:带懒,int,线段,tr,mid,cin,add,sum,模板
From: https://www.cnblogs.com/yuzian/p/16592016.html

相关文章

  • YbtOJ 「数据结构」第4章 线段树
    不想dp了怎么办?开个新坑吧。例题1.求区间和树状数组不香吗,28行解决(bushi所以懒得打线段树了。code#include<bits/stdc++.h>#defineintlonglongusingnamespac......
  • vm环境迁移后的ovf模板显示不兼容,“不支持客户机操作系统“centos7_64Guest””
    模板虚拟机开机告警:不支持客户机操作系统“centos7_64Guest”主机不能兼容操作系统,没有对应的驱动。   处理办法:     然后确定即可。 ......
  • 洛谷 P6242 【模板】线段树 3 吉司机线段树 区间取最小值 维护历史最大值和区间和
    题目背景本题是线段树维护区间最值操作与区间历史最值的模板。题目描述给出一个长度为 nn 的数列 AA,同时定义一个辅助数组 BB,BB 开始与 AA 完全相同。接下来......
  • 线段树----区间问题的神
    《标准线段树》  普通的线段树,其区间一般都是一个序列的数的个数,但还是要根据不同题目来判断注意:tr[]空间是N*4,N为最大范围《单点修改,区间查询》原题:https://www.......
  • 一些常用模板及函数(非竞赛)
    1.判断素数boolisPrime(intnum){ if(num==1)returnfalse; for(inti=2;i<=int(sqrt(num));i++) if(num%i==0) returntrue; returntrue;}......
  • EasyExecl导出模板,实现动态下拉列
    1.需要效果.  2.引入的jar包.<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><......
  • FusionAccess模板制作并发放
    FusionAccess安装并对接具体安装步骤欢迎参照我的博客:https://www.cnblogs.com/kongshuo/p/16333561.html在FC上创建win10虚拟机创建虚拟机,下一步名称随意,操作系统类......
  • Python语言开发基础模板
    内容概要基础阶段变量常量与用户交互输入/格式化输出基本运算符常见操作符逻辑运算符成员运算与身份运算分支结构之if分支循环结构之while循环循环结构之for循环变......
  • Shell语言开发基础模板
    内容概要基础阶段脚本处理/测试变量操作符分支结构之if分支分支结构之case分支循环结构之while循环循环结构之for循环函数脚本处理/测试#脚本处理window回车是......
  • Python调用函数模板
    内容概要函数阶段语法结构定义调用返回值参数名称空间闭包函数装饰器(难点)递归函数、二分法、匿名函数、三元表达式、列表生成式迭代器、生成器常见内置函数函数......