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

前缀和,线段树,树状数组,ST表四种数据结构的辨析

前缀和主要用于解决区间求和,线段数组主要用于动态的区间统计,ST表主要用于查询区间最值,线段树主要用于查询动态的区间最值

主要公式:

pre[i] = pre[i-1] + g[i]; pre[i][j] = g[i][j] - pre[i-1][j-1] + pre[i-1][j] + pre[i][j-1]; S = pre[x2][y2] + pre[x1-1][y1-1] - pre[x1-1][y2] - pre[x2][y1-1];

树状数组主要公式:单体添加,动态范围查询

static int lowbit(int x){ return x & -x; } static void add(int x,int v){ while(x<=n){ tree[x] += v; x += lowbit(x); } } static int sum(int x){ int res = 0; while(x>0){ res += tree[x]; x -= lowbit(x); } return res; }

注:一般范围查询就用sum(r) - sum(l-1);

ST表:主要用于静态范围查询最值,举个模版题

import java.util.*; import java.io.*; public class Main{ static int n; static int [] a; static int [][] st; static int [] log; public static void main(String[] args)throws Exception{ BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer stt = new StringTokenizer(bf.readLine()); n = Integer.parseInt(stt.nextToken()); int m = Integer.parseInt(stt.nextToken()); a = new int [n+1]; st = new int [n+1][20]; log = new int[n+1]; stt = new StringTokenizer(bf.readLine()); for(int i=1;i<=n;i++){ a[i] = Integer.parseInt(stt.nextToken()); st[i][0] = a[i]; } for(int i=2;i<=n;i++){ log[i] = log[i>>1] + 1; } for(int j=1;j<=log[n];j++){ for(int i=1;i+(1<<j)-1<=n;i++){ st[i][j] = Math.max(st[i][j-1],st[i+(1<<(j-1))][j-1]); } } StringBuilder sb = new StringBuilder(); while(m-->0){ stt = new StringTokenizer(bf.readLine()); int L = Integer.parseInt(stt.nextToken()); int R = Integer.parseInt(stt.nextToken()); int k = log[R-L+1]; int ans = Math.max(st[L][k],st[R-(1<<k)+1][k]); sb.append(ans).append("\n"); } System.out.print(sb.toString()); } }

注意两个地方:一个就是固定公式st[i][j] = Math.max(st[i][j-1],st[i+(1<<(j-1))][j-1]);

int ans = Math.max(st[L][k],st[R-(1<<k)+1][k]);

还有就是这题求的是最大值,如果要求最小值的话,把两个max换成min就可以了

离散化:数据很大又很乱时,但是你只关心数据的大小关系,而算法只需要下标时就可以用,举个例子:

import java.io.*; import java.util.*; public class Main { static int n; static int[] h; // 身高(离散化后是排名) static int[] tree; // 树状数组 // lowbit static int lowbit(int x) { return x & -x; } // 树状数组:单点加 1 static void add(int x, int v) { while (x <= n) { tree[x] += v; x += lowbit(x); } } // 树状数组:前缀和 static int sum(int x) { int res = 0; while (x > 0) { res += tree[x]; x -= lowbit(x); } return res; } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); n = Integer.parseInt(br.readLine()); h = new int[n]; for (int i = 0; i < n; i++) { h[i] = Integer.parseInt(br.readLine()); } // ====================== //离散化 // ====================== int[] b = h.clone(); Arrays.sort(b); // 去重 int m = 0; for (int i = 0; i < n; i++) { if (i == 0 || b[i] != b[i - 1]) { b[m++] = b[i]; } } // 映射为排名(1-based) for (int i = 0; i < n; i++) { h[i] = Arrays.binarySearch(b, 0, m, h[i]) + 1; } // ====================== //树状数组统计逆序对 // ====================== tree = new int[n + 1]; long ans = 0; for (int i = 0; i < n; i++) { int x = h[i]; // 左边比它大的数量 ans += i - sum(x); // 当前元素加入 add(x, 1); } System.out.println(ans); } }
http://www.cnnetsun.cn/news/95577.html

相关文章:

  • Jmeter 命令行压测生成HTML测试报告
  • AI编程系列——mcp与skill
  • 技术文章大纲:当云原生遇见VMware
  • AI Agent开发全攻略:2025年核心技术栈与学习资源,从新手到专家的蜕变之路!
  • LobeChat实体抽取能力在CRM中的应用
  • Java毕设项目:基于springboot天气预报查询系统(源码+文档,讲解、调试运行,定制等)
  • Netcode for GameObjects Boss Room 多人RPG战斗(6)
  • Java毕设项目:基于JavaWeb的心聘求职平台的设计与实现(源码+文档,讲解、调试运行,定制等)
  • Java毕设项目:基于JavaEE的电子印章管理系统的设计与实现(源码+文档,讲解、调试运行,定制等)
  • 5分钟梳理银行测试,文末附带实战项目,0经验入行so easy
  • 数据库基础
  • 基于单片机的家居净化器设计与实现
  • LeetCode 热题 100——图论——实现 Trie (前缀树)
  • 揭秘Java:深度解析线程调度算法!
  • 三大电商API应用对比:淘宝京东拼多多谁能笑到最后?
  • 2025年亲测7个降a率工具:AIGC率90%怎么降低ai?(附免费降AI1000字数)
  • ACL实验报告
  • 别再熬夜赶论文?6款AI工具帮你告别恐惧写作无压力!
  • 一键导入书签,首页替代神器!批量去重、自动备份,维护不再头疼
  • 土著刷题新功能解锁:跳题作答
  • Yolo模型TensorRT-C++推理实战指南
  • LobeChat能否支持暗能量建模?宇宙加速膨胀机制理论推演
  • 用python写一个简单的ros话题发布
  • 基于Java Swing的排序算法可视化器(1)
  • 不敢相信!这5个良心软件,功能强大到媲美付费版!
  • 实邦电子嵌入式开发服务如何,是否值得信赖?
  • 基于PLC控制的四路抢答器设计
  • 鸿蒙 Flutter 全场景开发实战指南:从环境搭建到分布式应用落地(2025 最新版)
  • LobeChat销售话术优化建议生成
  • 11章 像素和顶点数据导出 - “Vega“ 7nm Instruction Set ArchitectureReference Guide