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

单点修改、区间求和(模板)、区间修改,单点查询(模板)

题目描述

一行 NN 个方格,开始每个格子里都有一个整数。

你需要动态地进行一些操作,操作有以下两种类型:

  • 提问:求某一个特定的子区间 [a,b][a,b] 中所有元素的和;
  • 修改:指定某一个格子 xx,令 xx 加上或者减去一个特定的值 AA。

现在要求你能对每个提问作出正确的回答。

输入描述

输入文件第一行为一个整数 NN,接下来一行包含 nn 个整数,表示格子中原来的整数。

接下一个正整数 mm,再接下来有 mm 行,表示 mm 个询问。每个询问的第一个整数表示询问代号,询问代号 11 表示增加,后面的两个数 xx 和 AA 表示给位置 XX 上的数值增加 AA ,询问代号 22 表示区间求和,后面两个整数表示 aa 和 bb ,表示要求 [a,b][a,b] 之间的区间和。

1≤N,X,A≤100000,m≤100001≤N,X,A≤100000,m≤10000。

输出描述

共 mm 行,每行一个整数,表示每个提问的答案。

输入输出样例

示例

输入

6 4 5 6 2 1 3 4 1 3 5 2 1 4 1 1 9 2 2 6

输出

22 22

树状数组

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { static int N = 100010; static long c[]=new long[N]; static int a[]=new int[N]; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n=Integer.parseInt(br.readLine()); String g[] = br.readLine().split(" "); for (int i = 1; i <= n; i++) { add(i, Integer.parseInt(g[i-1]), n); } int m=Integer.parseInt(br.readLine()); for (int i = 0; i < m; i++) { g = br.readLine().split(" "); int op=Integer.parseInt(g[0]),a=Integer.parseInt(g[1]),b=Integer.parseInt(g[2]); if(op==1){ add(a,b,n);//添加类似于单点修改 }else{ long sum=query(b); long sum1=query(a-1); System.out.println(sum-sum1); } } } static int lowbit(int x){ return x & -x; } static void add(int x,int v,int n){ for (int i = x; i <= n; i+=lowbit(i)) { c[i]+=v; } } static long query(int a){ long res=0; for (int i = a; i >= 1; i-=lowbit(i)) { res+=c[i]; } return res; } }

线段树

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { static int N = 4*100010;//大小一般为4*N static long tree[]=new long[N]; static int a[]=new int[N]; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n=Integer.parseInt(br.readLine()); String g[] = br.readLine().split(" "); for (int i = 1; i <= n; i++) { a[i]=Integer.parseInt(g[i-1]); } build(1,1,n); int m=Integer.parseInt(br.readLine()); for (int i = 0; i < m; i++) { g = br.readLine().split(" "); int op=Integer.parseInt(g[0]),x=Integer.parseInt(g[1]),y=Integer.parseInt(g[2]); if(op==1){ update(1,1,n,x,y); }else{ long res=query(1,1,n,x,y); System.out.println(res); } } } static long query(int id,int l,int r,int ql,int qr){ if(l>=ql&& r<=qr){ return tree[id]; } int mid=(l+r)>>1; long res=0; if(ql<=mid)res+=query(2*id, l, mid, ql, qr); if(qr>=mid+1)res+=query(2*id+1, mid+1, r, ql, qr); return res; } static void update(int id,int l,int r,int pos,int x){ if(l==r){ tree[id]+=x; return; } int mid=(l+r)>>1; if(pos<=mid)update(2*id, l, mid, pos, x); else update(2*id+1, mid+1, r, pos, x); pushup(id); } static void pushup(int id){ tree[id]=tree[2*id]+tree[2*id+1]; } static void build(int id,int l,int r){ if(l==r){ tree[id]=a[l]; return; } int mid=(l+r)>>1; build(2*id, l, mid); build(2*id+1, mid+1, r); pushup(id); } }

区间修改,单点查询(模板)

问题描述

给定一个长度为 nn 的序列 aa,你需要进行 mm 次操作,每次操作为以下两种之一:

  • 1 l r x:将 al∼ral∼r​ 的所有数字增加 xx。
  • 2 idx:输出当前 aidxaidx​ 的值。

输入格式

第一行输入两个正整数 n,mn,m。(1≤n,m≤2×105)(1≤n,m≤2×105)

第二行输入 nn 个正整数 aiai​。(1≤ai≤104)(1≤ai​≤104)

接下来 mm 行,每行输入代表一种操作。

  • 1 l r x:将 al∼ral∼r​ 的所有数字增加 xx。
  • 2 idx:输出当前 aidxaidx​ 的值。

(1≤l≤r≤n,1≤x≤103,1≤idx≤n)(1≤l≤r≤n,1≤x≤103,1≤idx≤n)

输出格式

对于每次操作 22,输出对应的答案。

样例输入

3 2 1 2 3 1 1 3 1 2 2

样例输出3

树状数组写法

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { static int N = 2*100010; static long c[]=new long[N]; static int a[]=new int[N]; static int d[]=new int[N];//给差分数组建立树状数组 public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String g[] = br.readLine().split(" "); int n=Integer.parseInt(g[0]),m=Integer.parseInt(g[1]); g = br.readLine().split(" "); for (int i = 1; i <= n; i++) { a[i]=Integer.parseInt(g[i-1]); d[i]=a[i]-a[i-1]; } for (int i = 1; i <= n; i++) { add(i,d[i],n); } // 1 l r x:将l - r的所有数字增加 x。 // 2 idx:输出当前 a{idx} 的值。 for (int i = 0; i < m; i++) { g = br.readLine().split(" "); if(g.length==4){ int l=Integer.parseInt(g[1]),r=Integer.parseInt(g[2]),x=Integer.parseInt(g[3]); add(l,x,n);add(r+1,-x,n); }else{ int idx=Integer.parseInt(g[1]); int res=query(idx); System.out.println(res); } } } static int query(int idx){ int res=0; for (int i = idx; i>=1; i-=lowbit(i)) { res+=c[i]; } return res; } static void add(int pos,int x,int n){ for (int i = pos; i <= n; i+=lowbit(i)) { c[i]+=x; } } static int lowbit(int x){ return x & -x; } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { static int N = 4*200010; static int tree[]=new int[N]; static int a[]=new int[N]; static int d[]=new int[N];//给差分数组建立线段树 public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String g[] = br.readLine().split(" "); int n=Integer.parseInt(g[0]),m=Integer.parseInt(g[1]); g = br.readLine().split(" "); for (int i = 1; i <= n; i++) { a[i]=Integer.parseInt(g[i-1]); d[i]=a[i]-a[i-1]; } build(1,1,n); // 1 l r x:将l - r的所有数字增加 x。 // 2 idx:输出当前 a{idx} 的值。 for (int i = 0; i < m; i++) { g = br.readLine().split(" "); if(g.length==4){ int l=Integer.parseInt(g[1]),r=Integer.parseInt(g[2]),x=Integer.parseInt(g[3]); update(1,1,n,l,x);if(r+1<=n)update(1,1,n,r+1,-x); }else{ int idx=Integer.parseInt(g[1]); int res=query(1,1,n,1,idx); System.out.println(res); } } } static int query(int id,int l,int r,int ql,int qr) { if(l>=ql && r<=qr){//区间完全包含 return tree[id]; } int mid=(l+r)>>1; int res=0; if(ql<=mid)res+=query(2*id, l, mid, ql, qr); if(qr>=mid+1)res+=query(2*id+1, mid+1, r, ql, qr); return res; } static void update(int id,int l,int r,int pos,int x){ if(l==r){ tree[id]+=x; return; } int mid=(l+r)>>1; if(pos<=mid)update(2*id, l, mid, pos, x); else update(2*id+1, mid+1, r, pos, x); pushup(id); } static void build(int id,int l,int r){ if(l==r){ tree[id]=d[l]; return; } int mid=(l+r)>>1; build(2*id, l, mid); build(2*id+1, mid+1, r); pushup(id); } static void pushup(int id){ tree[id]=tree[2*id]+tree[2*id+1]; } }
http://www.rkmt.cn/news/1438883.html

相关文章:

  • 可观测性数据智能分析:AI如何赋能运维从监控到洞察
  • AI智能体安全盲区:传统安全分析为何失效及应对策略
  • 深入聊聊FPGA网络通信:为什么一个纯Verilog实现的、不带Ping功能的UDP协议栈反而更“香”?
  • 皇家守卫【算法赛】、百亿富翁、最大区间、附近最小
  • 厨房里的化学生态用鸿蒙PC的Electron框架实现
  • 用Python复现数学建模国赛C题:手把手教你用遗传算法优化电商物流网络(附完整代码)
  • dify一些bug解决
  • 别再只会ping了!用traceroute/tracert命令5分钟定位网络卡顿元凶(附Linux/Windows实战对比)
  • 从AirPods Pro到索尼XM5:拆解主流ANC耳机背后的‘混合动力’(Hybrid)技术到底强在哪?
  • 别再只套模型了!用Python+Matplotlib给你的数学建模结果做个‘稳定性体检’(灵敏度分析实战)
  • ADI DSP开发者的“寻宝图”:SigmaStudio+ 2.1安装包里那些被藏起来的ADSP-21569实战例程
  • 从气象雷达到SAR:不同波段(C/X/Ku)在实际项目中到底怎么选?
  • d3dx9_43.dll 丢失报错原因分析及三种标准修复方法
  • 流程图画法保姆级指南:从程序员思维到产品经理表达,三种循环结构一图搞定
  • MATLAB拉丁超立方采样工具包:支持相关性控制、经验分布与多种LHS算法实现
  • ThinkPHP开发的销售团队专用CRM源码,带客户公海、线索流转和多角色权限管理
  • 2026年新乡市黄金回收靠谱门店推荐 黄金+K金+白银+铂金回收门店TOP5排行榜+联系方式 - 盛世金银回收
  • 告别ISO!用VMware 17 Pro给Win11系统‘搬家’:GHO镜像+WePE启动盘的完整配置流程
  • 区块链与AI融合:破解数据孤岛与信任难题的技术新范式
  • 用89S52单片机驱动TPμP-40A微型打印机:一个嵌入式老项目的硬件接口与代码实战复盘
  • 制造业企业AI差旅管理数字化转型方案与头部平台实践分析 - 匠言榜单
  • 2026年鹰潭市黄金回收优选榜单|5家正规靠谱门店推荐+联系方式(黄金+K金+白银+铂金回收) - 盛世金银回收
  • 2018移动开发八大趋势:即时应用、云驱动、AR/VR与AI融合实战解析
  • 别再怕Go逆向!从‘hello’密码破解案例,掌握IDA静态分析与动态调试的核心思路
  • LVGL模拟器不止能看Demo:手把手教你修改源码,在Ubuntu上自定义你的第一个UI界面
  • 别再只配主备了!华为防火墙双机负载分担模式下,HRP配置主/备设备到底怎么玩?
  • AnchorRefine:层次化分解提升VLA模型在机器人精细操作中的精度
  • 别再傻傻分不清!乐谱上的‘V’和‘逗号’到底怎么用?一次搞懂换气与断句记号
  • 佛山市2026年最新黄金回收靠谱门店推荐 黄金+K金+白银+铂金回收门店TOP5排行榜+联系方式 - 大熊猫898989
  • PyTorch孪生网络实战:从原理到代码实现人脸相似度度量