树状数组学习笔记

news2024/12/23 20:15:44

树状数组

树状数组的用途,主要是可以以 O ( log ⁡ n ) O(\log n) O(logn) 的时间复杂度维护前缀和。

对于树状数组的使用,我们开一个数组 cc[x] 表示 [ x − lowbit ( x ) + 1 , x ] [x-\text{lowbit}(x)+1,x] [xlowbit(x)+1,x] 的区间和。

于是乎,c 数组就构成了这样的结构,我们称 c 为树状数组:

查询 x x x 的前缀和,代码如下:

int ask(int x)
{
    int res=0;
    while(x) res+=c[x],x-=lowbit(x);
    return res;
}

单点修改,将 x x x 增加 v v v,代码如下:

void add(int x,int v)
{
    while(x<=n) c[x]+=v,x+=lowbit(x);
    return;
}

树状数组 2

重点思想是通过差分把区间修改转化为单点修改。对于要记录的数组 a[i],假设有 d[i]=a[i]=a[i-1]d[1]=a[1],那么 a[i] 就等于从 d[1]d[i] 所有元素的和。我们存储的其实是 d 数组的树状数组。如果我们要把从 a[l]a[r] 区间内的所有元素加 1 1 1,其实从 d[l+1]d[r] 都没有变化,只需要 add(l,x)add(r+1,-x) 即可。

对于单点查询,由 a[i] 等于从 d[1]d[i] 的元素和可知,直接输出前缀和即 ask(i) 即可。

注意,由于这里我们其实是把 a 数组做了一个类似于差分的操作,所以在 add 的时候要加的是当前值与前一位的值的差。


二维树状数组

  • E. 【例题5】单点修改矩阵查询

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn=5005;
    ll n,m,c[maxn][maxn];
    
    int lowbit(int x){return x&(-x);}
    
    void add(int x,int y,int k)
    {
    	for(int i=x;i<=n;i+=lowbit(i))
    		for(int j=y;j<=m;j+=lowbit(j))
    			c[i][j]+=k;
    }
    
    ll query(int x,int y)
    {
    	ll sum=0;
    	for(int i=x;i;i-=lowbit(i))
    		for(int j=y;j;j-=lowbit(j)) sum+=c[i][j];
    	return sum;
    }
    
    int main()
    {
    	cin>>n>>m;
    	int opt;
    	while(cin>>opt)
    	{
    		if(opt==1) {int x,y,k;cin>>x>>y>>k,add(x,y,k);}
    		else 
    		{
    			int a,b,c,d;cin>>a>>b>>c>>d;
    			cout<<query(c,d)-query(c,b-1)-query(a-1,d)+query(a-1,b-1)<<endl;
    		}
    	}
    	return 0;
    }
    
  • F. 【例题6】矩阵修改矩阵查询

    #include<bits/stdc++.h>
    #define inl inline
    #define int long long
    #define ll long long
    
    using namespace std;
    const int N=2e3+50;
    int read()
    {
    	int sum=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    	while(isdigit(c)){sum=(sum<<3)+(sum<<1)+(c^48);c=getchar();}
    	return sum*f;
    }
    
    int lowbit(int x){return x&-x;}
    
    int t[N][N],ti[N][N],tj[N][N],tij[N][N];
    int n,m;
    
    inl void add(int x,int y,int k)
    {
    	for( int i=x;i<=n;i+=lowbit(i))
    		for( int j=y;j<=m;j+=lowbit(j))
            {
    			t[i][j]+=k;
    			ti[i][j]+=x*k;
    			tj[i][j]+=y*k;
    			tij[i][j]+=x*y*k;
    		}
    }
    
    ll query(int x,int y)
    {
    	int ans=0;
    	for( int i=x;i;i-=lowbit(i))
    		for( int j=y;j;j-=lowbit(j))
    			ans+=(x+1)*(y+1)*t[i][j]-ti[i][j]*(y+1)-tj[i][j]*(x+1)+tij[i][j];
    	return ans;
    }
    
    signed main()
    {
    	n=read(),m=read();
    	int opt;
    	while(scanf("%lld",&opt)!=EOF)
        {
    		int x=read(),y=read(),x2=read(),y2=read();
    		if(opt==1)
            {
    			int k=read();
    			add(x,y,k);add(x,y2+1,-k);add(x2+1,y,-k);add(x2+1,y2+1,k);
    		}
    		else
    			printf("%lld\n",query(x2,y2)+query(x-1,y-1)-query(x2,y-1)-query(x-1,y2));
    	}
    	return 0;
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1118060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图像超分辨率超分辨率NeRF论文阅读

文章目录 前置知识图像超分辨率《High-resolution image reconstruction with latent diffusion models from human brain activity》【CVPR23】《Dynamic High-Pass Filtering and Multi-Spectral Attention for Image Super-Resolution》【ICCV21】《DiffBIR: Towards Blind …

视频的二维码怎么做?教你一个实用技巧操作

现在扫码看视频越来越常见&#xff0c;很多人都会用这种方式来展示内容&#xff0c;比如展示环境、产品说明、自拍录像等等&#xff0c;让别人能够更快的获取内容。举个例子&#xff0c;当我们从淘宝或者其他购物平台买东西时&#xff0c;现在咨询客服询问使用说明时&#xff0…

HTML超链接标签

目录 1&#xff1a;页面间的链接 1.1 文字跳转&#xff1a; 1.2 图片跳转 2&#xff1a;锚链接 1&#xff1a;页面间的链接 1.1 文字跳转&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><t…

webpack(五)热更新

webpack-dev-serve 开启本地服务器 现状&#xff1a;打包后将index.html文件通过open in liveServe打开&#xff0c;我们继续修改js、html文件内容&#xff0c;页面没有变化。 解决方法&#xff1a; 方法一&#xff1a; 在打包命令后面加上--watch,重新打包后我们的终端不会终…

类的继承简介

一、声明格式&#xff1a; class 子类名&#xff1a;继承方式(public private protected) 父类名{子类成员表} 二、继承过程&#xff1a; 吸取父类成员——>改造父类成员——>添加新成员 三、作用&#xff1a; 子类会继承父类中的方法(不包括构造和析构函数)与属性 …

进阶JAVA篇-深入了解 List 系列集合

目录 1.0 List 类的说明 1.1 List 类的常用方法 1.2 List 集合的遍历方式 2.0 ArrayList 集合的底层原理 2.1 从 ArrayList 集合的底层原理来了解具有该特性的原因&#xff1a; 2.2 ArrayList 集合的优缺点 3.0 LinkedList 集合的底层原理 3.1 从 LinkedList 集合的底层原理来了…

卷积神经网络CNN学习笔记-卷积计算Conv2D函数的理解

目录 1.全连接层存在的问题2.卷积运算3.填充(padding)3.1填充(padding)的意义 4.步幅(stride)5.三维数据的卷积运算6.结合方块思考7.批处理8.Conv2D函数解析9.conv2d代码9.1 stride19.2 stride2 参考文章 1.全连接层存在的问题 在全连接层中&#xff0c;相邻层的神经元全部连接…

多线程-进阶

常见的锁策略 乐观锁和悲观锁 这不是两把具体的锁, 这是两类锁 乐观锁: 预测锁的竞争不是很激烈 悲观锁: 预测锁的竞争会很激烈 乐观和悲观说的都不是绝对的, 唯一的区分就是看预测锁竞争激烈程度的结论, 这两种锁的背后工作是截然不同的, 轻量级锁和重量级锁 轻量级锁加锁解…

浅谈人工智能视频分析技术的原理及行业场景应用

人工智能视频分析技术是利用计算机视觉、模式识别和深度学习算法等技术&#xff0c;对视频数据进行自动化处理和分析的过程。其基本工作原理包括以下几个步骤&#xff1a; 视频采集&#xff1a;通过摄像头或其他视频设备获取源视频数据。 视频预处理&#xff1a;对视频进行去噪…

如何更改eclipse的JDK版本

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、有时候导入一些网上的资源需要更换JDK二、使用步骤1. 总结 一、有时候导入一些网上的资源需要更换JDK 具体操作如下 二、使用步骤 1. 在eclipse上方工具栏找…

使用列表实现向量运算

向量内积 from operator import mul x [4, 6, 9] y [2, 2, 7] print(sum(map(mul, x, y)))相当于 x [4, 6, 9] y [2, 2, 7] print(sum((i*j for i, j in zip(x, y))))两个等长的向量对应元素相加 from operator import add x [4, 6, 9] y [2, 2, 7] print(list(map(ad…

一些经典的神经网络(第20天)

1. 经典神经网络&#xff08;LeNet&#xff09; LeNet是早期成功的神经网络&#xff1b; 先使用卷积层来学习图片空间信息 然后使用全连接层来转到到类别空间 【通过在卷积层后加入激活函数&#xff0c;可以引入非线性、增加模型的表达能力、增强稀疏性和解决梯度消失等问题…

基于RSSI的室内wifi定位系统 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; wifi室内定位系统 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;…

【经历】在职8个月->丰富且珍贵

在职8个月->丰富且珍贵 2021-3~2021-11&#xff1a;面试进入一家做400电话的公司&#xff0c;我进入公司时&#xff0c;加上我只有四个人(老板、人事、业务)&#xff0c;开发只有我&#xff0c;所以&#xff1a;产品~设计~前端~后端~测试~上线~维护~培训&#xff0c;只有我自…

并发性Socket通信源码(基于linux环境下多线程)

服务器端&#xff1a;server.c 1 #include <stdio.h>2 #include <stdlib.h>3 #include <unistd.h>4 #include <string.h>5 #include <arpa/inet.h>6 #include <pthread.h>7 void* working(void *arg);8 //信息结构体9 struct sockinfo10 …

烘焙蛋糕外卖小程序商城的作用是什么

随着经营成本上升及电商业态的冲击&#xff0c;传统烘焙蛋糕门店商家经营止步不前&#xff0c;加之口罩原因更是雪上加霜&#xff0c;引流拓客、经营转化复购大幅度降低&#xff0c;而线上又因外卖平台间的激烈竞争&#xff0c;导致中小烘焙蛋糕商家进退两难。 烘焙蛋糕店经营…

PO模式在selenium自动化测试框架的优势

大家都知道po模式可以提高代码的可读性和减少了代码的重复&#xff0c;但是相对的缺点还有&#xff0c;今天通过本文一起学习下PO模式在selenium自动化测试框架的优势&#xff0c;需要的朋友可以参考下 PO模式简介 1.什么是PO模式 PO模型是:Page Object Model的简写 页面对象…

使用 Sealos 一键私有化部署 Serverless 框架 Laf

太长不看&#xff1a;Laf 上架了 Sealos 的模板市场&#xff0c;通过 Laf 应用模板即可一键部署&#xff01; Laf 是一个完全开源的项目&#xff0c;除了使用公有云之外&#xff0c;还有大量的用户选择私有化部署 Laf。然而&#xff0c;私有化部署通常伴随着更多的复杂性和门槛…

java 实现定时任务

1、EnableScheduling spring自带的定时任务功能&#xff0c;使用比较简单方便&#xff1a; 1、需要定时执行的方法上加上Scheduled注解&#xff0c;这个注解中可以指定定时执行的规则&#xff0c;稍后详细介绍。 2、Spring容器中使用EnableScheduling开启定时任务的执行&…

解决找不到VCRUNTIME140_ 1.dll问题的5个方法分享

近日&#xff0c;许多用户在运行某些软件时遇到了“由于找不到VCRUNTIME140_1.dll无法继续执行此代码”的问题。这个错误通常出现在运行某些软件或游戏时&#xff0c;提示找不到必要的动态链接库文件。本文将详细VCRUNTIME140_ 1.dll文件是什么&#xff0c;并分享如何解决这个问…