当前位置: 首页 > news >正文

树状数组。

优点:修改和查询树状数组的前缀和复杂度为O(logn)

注意点:树状数组对下标有要求,必须从1开始(1-base)

1.求数组前缀和

将原数组数组放入树状数组直接求sum即可

2.求数组某个元素的值

将原数组的差分数组放入树状数组,求sum

3.求逆序对

知识点:离散化

目的:节约内存,让下表更清晰,去重节约时间复杂度

实现代码

sort(t+1,t+n+1); cnt=unique(t+1,t+n+1)-t-1;

将离散化后的数组按顺序插入树状数组,求前缀和n-前缀和a[i].

模板:

#include <bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false),cin.tie(0); #define endl "\n" #define pb push_back #define dbg(x) std::cout<<#x<<":"<<x<<" " typedef long long ll; typedef pair<int,int> PII; const int N=500005; ll n,m; ll a[N]; ll lowbit(ll x) { return (x&(-x)); } void update(ll x,ll v){ while(x<=n){ a[x]+=v; x+=lowbit(x); } } ll sum(ll x){ ll res=0; while(x>0){ res+=a[x]; x-=lowbit(x); } return res; } void solve() { cin>>n>>m; ll w=n; ll tp; while(w--){ cin>>tp; update(n-w,tp); } ll a1,a2,a3; while(m--){ cin>>a1>>a2>>a3; if(a1==1){ update(a2,a3); } if(a1==2){ if(a2>1) cout<<sum(a3)-sum(a2-1)<<endl; else cout<<sum(a3)<<endl; } } } int main() { IOS int T=1;//cin>>T; while(T--) solve(); return 0; }

#include <bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false),cin.tie(0); #define endl "\n" #define pb push_back #define dbg(x) std::cout<<#x<<":"<<x<<" " typedef long long ll; typedef pair<int,int> PII; const int N=500005; int n,m; int a[N],b[N]; int lowbit(int x) { return (x&(-x)); } void update(int x,ll v){ while(x<=n){ a[x]+=v; x+=lowbit(x); } } ll sum(int x){ ll res=0; while(x>0){ res+=a[x]; x-=lowbit(x); } return res; } void solve() { cin>>n>>m; int w=n; ll tp; for(int i=1;i<=n;i++){ cin>>b[i]; update(i,b[i]-b[i-1]); } ll a1,a2,a3,a4; while(m--){ cin>>a1; if(a1==1){ cin>>a2>>a3>>a4; update(a2,a4); update(a3+1,-a4); } if(a1==2){ cin>>a2; cout<<sum(a2)<<endl; } } } int main() { IOS int T=1;//cin>>T; while(T--) solve(); return 0; }

例题:

题都不难,放了几个典型的

洛谷——逆序对

#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e5+5; int n,cnt; ll a[N],b[N],t[N],ans; int lowbit(int x){ return x&(-x); } void update(int x){ while(x<=n){ a[x]++; x+=lowbit(x); } } ll sum(int x){ ll res=0; while(x>0){ res+=a[x]; x-=lowbit(x); } return res; } void solve() { cin>>n; for(int i=1;i<=n;i++){ cin>>b[i]; t[i]=b[i]; } sort(t+1,t+n+1); cnt=unique(t+1,t+n+1)-t-1; for(int i=1;i<=n;i++){ //按原顺序插入 b[i]=lower_bound(t+1,t+cnt+1,b[i])-t;//更新离散化后的序号 update(b[i]); //比当前元素大的=当前元素个数-小于等于它的元素个数 ans+=sum(n)-sum(b[i]); } printf("%lld\n",ans); } int main() { solve(); return 0; }

数星星

可以不用逆序对

#include <bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false),cin.tie(0); #define endl "\n" #define pb push_back #define dbg(x) std::cout<<#x<<":"<<x<<" " typedef long long ll; typedef pair<int,int> PII; const int N=32005; struct z{ int x,y; }; int n,m,MAX=0; int a[N],ans[N]; z p[N]; int lowbit(int x) { return (x&(-x)); } void update(int x,int v){ while(x<=N){ a[x]+=v; x+=lowbit(x); } } ll sum(int x){ ll res=0; while(x>0){ res+=a[x]; x-=lowbit(x); } return res; } void solve() { scanf("%d",&n); int x,y; for(int i=1;i<=n;i++){ scanf("%d %d",&p[i].x,&p[i].y); } for(int i=1;i<=n;i++){ update(p[i].x+1,1); int v=sum(p[i].x+1); ans[v-1]++; } for(int i=0;i<n;i++){ cout<<ans[i]<<endl; } } int main() { int T=1;//cin>>T; while(T--) solve(); return 0; }

逆序对写法和上个题基本一样按顺序求x的逆序对就好了,不写了

其实这个题有别的做法

我把update里的加改成了异或

#include <bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false),cin.tie(0); #define endl "\n" #define pb push_back #define dbg(x) std::cout<<#x<<":"<<x<<" " typedef long long ll; typedef pair<int,int> PII; const int N=5000005; int n,m; int a[N],b[N]; int lowbit(int x) { return (x&(-x)); } void update(int x,int v){ while(x<=n){ a[x]^=v; x+=lowbit(x); } } ll sum(int x){ ll res=0; while(x>0){ res^=a[x]; x-=lowbit(x); } return res; } void solve() { cin>>n>>m; ll a1,a2,a3; while(m--){ scanf("%lld",&a1); if(a1==1){ scanf("%lld %lld",&a2,&a3); update(a2,1); update(a3+1,1); } if(a1==2){ scanf("%lld",&a2); cout<<sum(a2)<<endl; } } } int main() { int T=1;//cin>>T; while(T--) solve(); return 0; }
http://www.jsqmd.com/news/1170088/

相关文章:

  • A3908电机驱动器与PIC32MX795F512L微控制器的精密运动控制方案
  • 从零构建专业级Windows屏幕标注工具:ppInk的技术架构深度解析
  • 2026年广西联通流量卡办理攻略:19、29元套餐怎么选、在哪办、避坑全讲清 - 中凡科技
  • OpenClaw本地智能体中枢系统:原理、安装与网关技能协同
  • 加厚抽纸哪家好:联盛森宝业内一流 - MXyuyu
  • XTerminal使用流程
  • TMC7300与STM32L4A6RG的有刷直流电机控制方案
  • 除 Word 外,还有哪些免费工具能搞定整套毕业论文排版?
  • 可湿水抽纸哪家靠谱:联盛森宝服务周全 - MXyuyu
  • 告别臃肿系统!openEuler/imageTailor让你的镜像瘦身90%的秘密
  • 3步完成Windows安卓应用安装:APK Installer终极指南
  • SAP EWM 过账更改深度解析:4类仓库任务与MES集成通知机制
  • 宠物用纸哪家好:联盛森宝行业标杆 - MXyuyu
  • ROS2 Humble Docker镜像 + VSCode Dev Containers:5个关键插件配置与性能优化
  • 基于蓝牙5.4与STM32的高保真无线音频系统设计
  • 葡萄牙国际物联网卡|葡萄牙本土网络适配、区域工况与落地应用指南
  • 2026江西文武学校怎么选?嵩山少林小龙文武学校2026年招生简章报名入口 - 全国文武学校招生
  • STM32F407 CANopen 主站节点配置:3步构建对象字典与节点状态管理
  • 50 Canvas 动画:@State + @Watch + animateTo 驱动模式
  • oeGitExt高级用法:如何批量管理issues与自动化代码审查的终极指南
  • 2026年7月最新金华天梭官方售后联系电话与客户服务中心网点地址 - 天梭服务中心
  • riskmoduler-工业级信用评分卡建模平台,一键自动建模,生成模型报告
  • 腾讯Hy3模型免费体验:智能体工作流与混合专家架构实战
  • 原生木浆湿厕纸推荐:联盛森宝服务领军 - MXyuyu
  • Unity移动端YOLOv8部署:Sentis推理与C# NMS后处理优化实战
  • PIC24FV32KA304上拉下拉配置与DTH-08接口设计
  • 基于PINNS物理神经网络的简单N-S方程逆参数求解代码
  • 3个实用技巧:使用openEuler Raspberry Pi Kernel优化树莓派性能
  • 工业级机器学习建模智能平台,一键懒人模式,秒级建模
  • syscontainer-tools 性能优化:10 个提升容器管理效率的技巧