首页 > 其他分享 >线段树的一些板子

线段树的一些板子

时间:2022-10-27 19:00:19浏览次数:51  
标签:md return int 线段 板子 k2 build 一些 sum

有2种方式,都是用的lazy标记,但具体用法不同

 

1)标记永久化

 

假设现在需要

1.区间加值 2.求区间和 

 

#include <iostream>
#include <algorithm>
using namespace std ;
 const int N=1e5+2;
 
#define int long long 
 
 int sum[N<<2],lazy[N<<2],n,a[N];
 int X,Y,_sum;
 
 void q(int o,int l,int r){
     if(X<=l&&Y>=r){
         _sum+=sum[o]+lazy[o]*(r-l+1); return;
     }
     _sum+=(min(Y,r)-max(l,X)+1)*lazy[o];
     int md=(l+r)/2; 
     if(X<=md) q(o*2,l,md);
     if(Y>md) q(o*2+1,md+1,r);
 }
 void add(int o,int l,int r,int z){
     if(X<=l&&Y>=r){
         lazy[o]+=z;  return;
     }
     sum[o]+=(min(Y,r)-max(l,X)+1)*z;
     int md=(l+r)/2;
     if(X<=md) add(o*2,l,md,z);
    if(Y>md) add(o*2+1,md+1,r,z);
 }
 void build(int o,int l,int r){
     lazy[o]=0;
     if(l==r){
         sum[o]=a[l];  return;
     }
     int md=(l+r)/2;
     build(o*2,l,md); build(o*2+1,md+1,r);
     sum[o]=sum[o*2]+sum[o*2+1];
 }
 signed main(){
 //    freopen("in","r",stdin);
     int i,T,op,z;
     cin>>n>>T;
     for(i=1;i<=n;i++) cin>>a[i];
     build(1,1,n);
     
     while(T--){
         cin>>op>>X>>Y;
           if(op==1){
               cin>>z; add(1,1,n,z);
           }
           else{
               _sum=0;
               q(1,1,n); 
               cout<<_sum<<endl;
           }
     }
 }
 
 

 

2)标记下传

#define k1 k<<1
#define k2 k<<1|1
#define int long long 
 
 int sum[N<<2],lazy[N<<2],n,a[N];
 
 void help(int k,int l,int r,int v){
     lazy[k]+=v,sum[k]+=(r-l+1)*v;
 }
 void pushd(int k,int l,int r){
     int md=(l+r)/2; 
     if(!lazy[k]) return;
     
     help(k1,l,md,lazy[k]),help(k2,md+1,r,lazy[k]); 
     lazy[k]=0;
 }
 int qry(int k,int l,int r,int x,int y){
     int t=0;
     if(x<=l&&y>=r)
         return sum[k];
     
     int md=(l+r)/2; 
     pushd(k,l,r);
     if(x<=md) t+=qry(k1,l,md,x,y);
     if(y>md) t+=qry(k2,md+1,r,x,y);
     return t;
 }
 void add(int k,int l,int r,int x,int y,int z){
     if(x<=l&&y>=r) return help(k,l,r,z);
     
     int md=(l+r)/2;
     pushd(k,l,r);
     if(x<=md) add(k1,l,md,x,y,z);
    if(y>md) add(k2,md+1,r,x,y,z);
    
     sum[k]=sum[k1]+sum[k2];
 }
 void build(int k,int l,int r){
     if(l==r){
         sum[k]=a[l]; return;
     }
     int md=(l+r)/2;
     build(k1,l,md),build(k2,md+1,r);
     sum[k]=sum[k1]+sum[k2];
 }

 

标签:md,return,int,线段,板子,k2,build,一些,sum
From: https://www.cnblogs.com/towboa/p/16833351.html

相关文章

  • luogu 1908 逆序对板子
     逆序对的本质是二维偏序 给第一维排序(输入时已排好),统计y(k)>=y(i)k<i的个数用树状数组维护y值前缀和,需要的时候直接查询该题需要离散化这个y,再作为树状数组......
  • mybatis增删改查的一些学习代码
    1.UserMapper.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/......
  • 推荐一些 OJ 平台
    嗯,对于刚进入OI学的小白,我这里有一些OJ平台仅供参考。洛谷AcwingCodeforcesAtCoderPOJ洛谷的题很丰富,最近还新加了蓝桥杯的题目,但是有些用户总爱跟风。(强调一......
  • 整理一些关于树的力扣热门算法操作
    一、LC94、144、145中序,前序,后续遍历List<Integer>front=newArrayList<>();List<Integer>mid=newArrayList<>();List<Integer>back=newArrayList<>();......
  • 一些常用SQL
    Dataworks(Maxcompute)获取昨天日期selectreplace(date_add(getdate(),-1),'-','')Hologres(pgsql)pg_typeof()类似python中的type()函数,用于获取数据类型select......
  • git idea使用的一些事
    提示:有部分是根据自己的需求网络合并的类名各种颜色代表的含义在安装了git以后发现idea类名出现了不同的颜色,如下:它们分别表示的含义:绿色,已经加入控制暂未提交红色,......
  • Util类 为了代码复用将一些连接数据库的代码
    importjava.sql.*;//导入包publicclassUtil1{//基本配置staticfinalStringJDBC_DRIVER="com.mysql.cj.jdbc.Driver"; staticfinalStringDB_URL="jdbc:m......
  • python的一些运算符
    #1.算术运算符print('1.算术运算符')#1.1+求和a=10b=20c=a+bprint(c)print('a+b={}'.format(c))print('a+b=%i'%c)print(f'a+b={c}')#1.2-求......
  • minio 对象存储部署一些说明
    一个minio简单部署使用说明,以前写过一些简单的,主要扩展下,对于优化相关的具体可以参考官方的以及linux相关优化的文章参考部署  可靠性玩法可以开启多版本开启......
  • 线段树
    题目1:(带懒标记的线段树)给定一个长度为 NN 的数列 AA,以及 MM 条指令,每条指令可能是以下两种之一:Clrd,表示把 A[l],A[l+1],…,A[r]A[l],A[l+1],…,A[r] 都加上 ......