首页 > 其他分享 >线段树:区间修改,区间查询

线段树:区间修改,区间查询

时间:2024-11-01 12:51:53浏览次数:3  
标签:10 lazy ch 数列 int 线段 long 查询 区间

Description

这是一道模板题。

给定数列 ,你需要依次进行  个操作,操作有两类:

  • 1 l r x:给定 ,对于所有 ,将  加上 (换言之,将  分别加上 );
  • 2 l r:给定 ,求  的值(换言之,求  的值)。
Input

第一行包含  个正整数 ,表示数列长度和询问个数。保证 。
第二行  个整数 ,表示初始数列。保证 。
接下来  行,每行一个操作,为以下两种之一:

  • 1 l r x:对于所有 ,将  加上 ;
  • 2 l r:输出  的值。

保证  。

Output

对于每个 2 l r 操作,输出一行,每行有一个整数,表示所求的结果。


  • Sample Input
    5 10
    2 6 6 1 1
    2 1 4
    1 2 5 10
    2 1 3
    2 2 3
    1 2 2 8
    1 2 3 7
    1 4 4 10
    2 1 2
    1 4 5 6
    2 3 4
  • Sample Output
    15
    34
    32
    33
    50

#include <bits/stdc++.h>
#define int long long
#pragma GCC optimize(2)
   
using namespace std;
    
int a[1000001], n, m;
int sum[4000001];
int lazy[4000001];
   
inline void write( int x )
{
    if( x < 0 )
    {
        putchar('-');
        x = -x;
    }
       
    if( x > 9 ) 
    {
        write( x / 10 );
    }
       
    putchar( x % 10 + '0' );
}
       
inline long long read()
{
    char ch = getchar();
    long long r = 0, w = 1;
    while( ch < '0' || ch > '9' ) w = ch == '-' ? -1 : w, ch = getchar();
    while( ch >= '0' && ch <= '9' ) r = r * 10 + ch - '0', ch = getchar();
    return r * w;
}
   
inline void pushdown( int p, int t )
{
    sum[p<<1] += ( t - (t >> 1) ) * lazy[p];
    lazy[p<<1] += lazy[p];
    sum[p<<1|1] += ( t >> 1 ) * lazy[p];
    lazy[p<<1|1] += lazy[p];
    lazy[p] = 0;
}
    
inline void build( int p, int l, int r )
{
    if( l == r )
    {
        sum[p] = a[l];
        return ;
    }
       
    int mid = ( l + r ) >> 1;
    build( p << 1, l, mid );
    build( p << 1 | 1, mid + 1, r );
    sum[p] = sum[p<<1] + sum[p<<1|1];
}
    
inline int query( int p, int l, int r, int x, int y )
{
    if( x <= l && r <= y )
    {
        return sum[p];
    }
       
    int mid = ( l + r ) >> 1;
    int ans = 0;
       
    pushdown( p, r - l + 1 );
       
    if( x <= mid )
    {
        ans += query( p << 1, l, mid, x, y );
    }
       
    if( y > mid )
    {
        ans += query( p << 1 | 1, mid + 1, r, x, y );
    }
       
    return ans;
}
   
inline void update( int p, int l, int r, int x, int y, int num )
{
    if( x <= l && r <= y )
    {
        sum[p] += ( r - l + 1 ) * num;
        lazy[p] += num;
        return ;
    }
       
    pushdown( p, r - l + 1 );
       
    int mid = ( l + r ) >> 1;
       
    if( x <= mid ) update( p << 1, l, mid, x, y, num );
    if( mid < y ) update( p << 1 | 1, mid + 1, r, x, y, num );
       
    sum[p] = sum[p<<1] + sum[p<<1|1];
}
    
signed main()
{
    n = read(), m = read();
       
    for( int i = 1; i <= n; i++ )
    {
        a[i] = read();
    }
       
    build( 1, 1, n );
       
    while( m-- )
    {
        int op;
           
        op = read();
           
        if( op == 1 )
        {
            int l, r, x;
            l = read(), r = read(), x = read();
            update(1, 1, n, l, r, x );
        }
        else
        {
            int l, r;
            l = read(), r = read();
            write( query( 1, 1, n, l, r ) );
            putchar( '\n' );
        }
    }
       
    return 0;
}

标签:10,lazy,ch,数列,int,线段,long,查询,区间
From: https://blog.csdn.net/m0_73232096/article/details/143393244

相关文章

  • rk3576 查询npu频率
    rk3576查询npu频率cat/sys/kernel/debug/rknpu/freq设置NPU工作频率:#以RK3588为例#查看NPU可用频率cat/sys/class/devfreq/fdab0000.npu/available_frequencies#设置NPU频率,例如,设置1GHzecho1000000000>/sys/kernel/debug/rknpu/freq   (1)查询NPU......
  • 区间集合:高效解决无重叠区间问题【贪心、区间集合】
    无重叠区间问题的深入解析与C++实现题目理解在无重叠区间问题中,我们被给定一个区间集合intervals,其中每个区间以[start,end]的形式表示。我们的目标是确定最少需要移除多少个区间,以确保剩下的区间互不重叠。值得注意的是,当两个区间仅在一个点上接触时(例如[1,2]和[......
  • 基于Java+SpringBoot+Vue+HTML5库存管理系统(源码+LW+调试文档+讲解等)/库存管理/库存
    博主介绍......
  • 区间和---使用离散化
    假定有一个无限长的数轴,数轴上每个坐标上的数都是0。现在,我们首先进行n次操作,每次操作将某一位置x上的数加c。接下来,进行m次询问,每个询问包含两个整数l和r,你需要求出在区间[l,r]之间的所有数的和。#include<iostream>#include<vector>#include<algorithm>usingn......
  • mysql 连表查询太慢
    优化joinon性能,解决联表查询慢的问题这里只提供一种方式啊,就是如果连表有查询条件,那就先把条件查了,然后再连表,这个很有用比如:pub_user1与pub_user2有相同的字段user_id直接这么写会多查询很多数据SELECTa.user_id,a.user_name,b.user_c......
  • 线段树 & 树状数组
    线段树常用于维护区间值代码和题解有很大差异,但是过了就好voidPushup(intx){ s[x]=(s[x<<1]+s[x<<1|1]);}voidPushdown(intx,intl,intr){ s[x]=(s[x]+ad[x]*(r-l+1)); if(l!=r)ad[x<<1]=(ad[x<<1]+ad[x]); if(l!=r)ad[x<<1|1]=(ad[x<<1|1]+ad[x......
  • 刷题总结——区间和
    前缀和前缀和是一种解决区间求和问题的辅助方法,前缀和只适用于固定区间(数组、树等),如果区间元素发生变化,则不适用,此时需要考虑树状数组、线段树等方式。问题类型常见的问题也是和DP一样,求最大/最小/方案数。类型题目备注前缀和+哈希LC560两数之和思路前缀和+......
  • 基于Java+SpringBoot+Vue+HTML5图书管理系统(源码+LW+调试文档+讲解等)/图书馆管理系
    博主介绍......
  • Rollup与查询
    Rollup与查询-ApacheDorishttps://doris.apache.org/zh-CN/docs/1.2/data-table/hit-the-rollup/Rollup与查询ROLLUP在多维分析中是“上卷”的意思,即将数据按某种指定的粒度进行进一步聚合。基本概念​在Doris中,我们将用户通过建表语句创建出来的表称为Base表(BaseT......
  • 在 SQL 中,有许多高效、简洁的函数可用于数据处理、查询优化和数据转换。
    以下是一些常见的SQL函数及其详细中文解释、示例和总结:1.COALESCE作用:COALESCE函数从左到右依次检查其参数,并返回第一个非空的值。如果所有参数都为空,则返回NULL。应用场景:可以在处理缺失数据时使用,尤其是多个字段可能为空的情况下,可以选择一个优先级最高的非空值。......