23、区间和

news2025/6/22 17:37:53

区间和

题目描述

假定有一个无限长的数轴,数轴上每个坐标上的数都是0。

现在,我们首先进行 n 次操作,每次操作将某一位置x上的数加c。

接下来,进行 m 次询问,每个询问包含两个整数l和r,你需要求出在区间[l, r]之间的所有数的和。

输入格式

第一行包含两个整数n和m。

接下来 n 行,每行包含两个整数x和c。

再接下里 m 行,每行包含两个整数l和r。

输出格式

共m行,每行输出一个询问中所求的区间内数字和。

数据范围

$ −109≤x≤109,$
$ 1≤n,m≤10^5,$
$ −109≤l≤r≤109,$
$ −10000≤c≤10000$

输入样例:

3 3
1 2
3 6
7 5
1 3
4 6
7 8

输出样例:

8
0
5

Solution

  1. 用题目中会用到的数字最多有 3 * 10^5,可以用来离散化表示 10^9
  2. alls 存所有用到的下标,adds 存所有添加操作,querys 存所有查询操作
  3. a 存执行添加操作之后的下标的值,q 存前缀和

用二维数组代替 Pairs,用数组代替 List,速度快了一倍

import java.util.*;
import java.io.*;

class Main{
    static final int N = 100010;
    static int[] a = new int[3 * N];
    static int[] q = new int[3 * N];
    static int[][] adds = new int[N][2];
    static int[][] querys = new int[N][2];
    static int[] alls = new int[3 * N];
    public static int unique(int[] alls, int n){
        // 双指针
        int j = 0;
        for(int i = 0; i < n; i++){
            if(i == 0 || alls[i] != alls[i - 1]){
                alls[j] = alls[i];
                j++;
            }
        }
        return j;
    }
    public static int bsearch(int[] alls, int n, int x){
        int low = 0, high = n - 1;
        while(low <= high){
            int mid = low + high >> 1;
            if(alls[mid] > x) high = mid - 1;
            else if(alls[mid] < x) low = mid + 1;
            else return mid + 1;
        }
        return low;
    }
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = br.readLine().split(" ");
        int n = Integer.parseInt(s[0]);
        int m = Integer.parseInt(s[1]);
        // 下标
        int idx = 0, idx1 = 0;
        // 存插入
        for(int i = 0; i < n; i++){
            s = br.readLine().split(" ");
            int x = Integer.parseInt(s[0]);
            int c = Integer.parseInt(s[1]);
            alls[idx++] = x;
            adds[i][0] = x;
            adds[i][1] = c;
        }
        for(int i = 0; i < m; i++){
            s = br.readLine().split(" ");
            int l = Integer.parseInt(s[0]);
            int r = Integer.parseInt(s[1]);
            alls[idx++] = l;
            alls[idx++] = r;
            querys[i][0] = l;
            querys[i][1] = r;
        }
        // alls(0, idx - 1) 排序
        Arrays.sort(alls, 0, idx);
        // 去重
        int end = unique(alls, idx);
        // 添加操作
        for(int i = 0; i < n; i++){
            // 二分查找找到 x 在 alls 数组中的下标
            int t = bsearch(alls, end, adds[i][0]);
            a[t] += adds[i][1];
        }
        // 计算前缀和
        for(int i = 1; i <= end; i++){
            q[i] = q[i - 1] + a[i];
        }
        for(int i = 0; i < m; i++){
            int l = bsearch(alls, end, querys[i][0]);
            int r = bsearch(alls, end, querys[i][1]);
            bw.write(q[r] - q[l - 1] + "\n");
        }
        bw.close();
        br.close();
        
    }
}

用了 List 和 Pairs,效率不高

import java.util.*;
import java.io.*;

public class Main{
    static class Pairs{
        int first, second;
        public Pairs(int first, int second){
            this.first = first;
            this.second = second;
        }
    }
    public static void main(String[] args) throws IOException{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = in.readLine().split(" ");
        int n = Integer.parseInt(s[0]);
        int m = Integer.parseInt(s[1]);
        // 数据范围为 10 的 9 次方,如果直接一个数组来存,空间就会超出限制
        // 但是操作数和查询数只有 10 的 5 次方
        // 想到用离散化的方式,用 10 的 5 次方的长度表示 10 的 9 次方的量级
        // 申请的数组长度 n + m + m + 10 就可以,加个 10 防止边界问题
        int N = n + m + m + 10;
        // a[] 去重,离散化之后的数组
        int[] a = new int[N];
        // p[] a的前缀和
        int[] p = new int[N];
        // adds 记录添加操作
        List<Pairs> adds = new ArrayList<>();
        // querys 记录查询操作
        List<Pairs> querys = new ArrayList<>();
        // alls 记录所有在数轴上出现过的坐标
        List<Integer> alls = new ArrayList<>();
        for(int i = 0; i < n; i++){
            s = in.readLine().split(" ");
            int x = Integer.parseInt(s[0]);
            int c = Integer.parseInt(s[1]);
            adds.add(new Pairs(x, c));
            alls.add(x);
        }
        
        for(int i = 0; i < m; i++){
            s = in.readLine().split(" ");
            int l = Integer.parseInt(s[0]);
            int r = Integer.parseInt(s[1]);
            
            querys.add(new Pairs(l, r));
            alls.add(l);
            alls.add(r);
        }
        // 排序
        Collections.sort(alls);
        // 去重
        int end = unique(alls);
        alls = alls.subList(0, end);

        // 离散化,就是找到要插入或者查询的数字在 alls 的位置
        // 可以用二分查找
        // 插入
        // 返回值以 1 开始计数
        for(int i = 0; i < n; i++){
            int index = bsearch(adds.get(i).first, alls);
            a[index] += adds.get(i).second;
        }

        // 计算前缀和
        for(int i = 1; i < N; i++){
            p[i] = p[i - 1] + a[i];
        }

        // 开始查询输出
        for(int i = 0; i < m; i++){
            int l = bsearch(querys.get(i).first, alls);
            int r = bsearch(querys.get(i).second, alls);
            int res = p[r] - p[l - 1];
            out.write(res + "\n");
            out.flush();
        }
    }
    public static int unique(List<Integer> list){
        int j = 0;
        for(int i = 0; i < list.size(); i++){
            if(i == 0 || list.get(i) != list.get(i - 1)){
                list.set(j, list.get(i));
                j++;
            }
        }
        return j;
    }
    public static int bsearch(int x, List<Integer> list){
        int l = 0, r = list.size() - 1;
        while(l <= r){
            int mid = l + r >> 1;
            if(list.get(mid) > x) r = mid - 1;
            else if(list.get(mid) < x) l = mid + 1;
            else return mid + 1;
        }
        return 1;
    }
}

yxc

  1. 离散化

在这里插入图片描述

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

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

相关文章

02-结构化程式与自定义函数

视频教程&#xff1a;b站视频【MATLAB教程_台大郭彦甫&#xff08;14课&#xff09;原视频补档】https://www.bilibili.com/video/BV1GJ41137UH/?share_sourcecopy_web&vd_sourc*ed6b9f96888e9c85118cb40c164875dfc 官网教程&#xff1a; MATLAB 快速入门 - MathWorks 中…

Java面试题戏剧

目录 第一幕 、第一场&#xff09;某大厦楼下大门前第二场&#xff09;电梯中第三场&#xff09;走廊中 第二幕、第一场&#xff09;公司前台第二场&#xff09;公司卫生间 第三幕、第一场&#xff09;一场异常面试 第四幕 、第一场&#xff09;大厦楼下门口第二场&#xff09;…

InternVideo2重塑视频理解新标杆,多模态学习引领行业风向

引言&#xff1a;视频理解的新篇章——InternVideo2的介绍 随着视频内容在日常生活中的普及&#xff0c;视频理解技术的重要性日益凸显。视频不仅包含丰富的视觉信息&#xff0c;还蕴含着动态变化和多模态元素&#xff0c;如音频和文本。这些特性使得视频成为一个复杂的数据类型…

【Python】科研代码学习:十七 模型参数合并,safetensors / bin

【Python】科研代码学习&#xff1a;十七 模型参数合并&#xff0c;safetensors / bin 前言解决代码知识点&#xff1a;safetensors 和 bin 的区别&#xff1f;知识点&#xff1a;save_pretrained 还会新增的文件知识点&#xff1a;在保存模型参数时&#xff0c;大小发生了成倍…

【Linux的进程篇章 - 进程终止和进程等待的理解】

Linux学习笔记---008 Linux之fork函数、进程终止和等待的理解1、fork函数1.1、什么是fork?1.2、fork的功能介绍1.3、fork函数返回值的理解1.4、fork函数的总结 2、进程的终止2.1、终止是在做什么&#xff1f;2.2、进程终止的3种情况 3、进程的终止3.1、进程终止的三种情况3.2、…

数据结构-移除元素(简单)

题目描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…

pycharm debug 的时候 waiting for process detach

当你使用pycharm debug或者run的时候&#xff0c;突然出现了点不动&#xff0c;然后一直显示&#xff1a;waiting for process detach 可能是以下问题&#xff1a; 1、需要设置Gevent compatible pycharm一直没显示运行步骤&#xff0c;只是出现waiting for process detach-C…

Day04-SHELL自动化编程-循环与颜色函数库

Day04-SHELL自动化编程-循环与颜色函数库 11. 必知必会核心命令11.1 命令概述11.7 案例11.8 小结 12 Shell编程-循环12.1 循环概述12.2 for循环1&#xff09;最常用的for循环格式2&#xff09;c语言格式for循环3&#xff09;for循环格式及应用场景4&#xff09;案例 12.3 while…

数据结构(三)----栈和队列

目录 一.栈 1.栈的基本概念 2.栈的基本操作 3.顺序栈的实现 •顺序栈的定义 •顺序栈的初始化 •进栈操作 •出栈操作 •读栈顶元素操作 •若使用另一种方式: 4.链栈的实现 •链栈的进栈操作 •链栈的出栈操作 •读栈顶元素 二.队列 1.队列的基本概念 2.队列的基…

【TensorRT】TensorRT C# API 项目更新 (1):支持动态Bath输入模型推理(下篇)

4. 接口应用 关于该项目的调用方式在上一篇文章中已经进行了详细介绍&#xff0c;具体使用可以参考《最新发布&#xff01;TensorRT C# API &#xff1a;基于C#与TensorRT部署深度学习模型》&#xff0c;下面结合Yolov8-cls模型详细介绍一下更新的接口使用方法。 4.1 创建并配…

Ubuntu配置VScode的C++环境

在Ubuntu系统下配置C环境&#xff0c;并运行helloworld 1. 下载VScode 我这里使用的是星火应用商店&#xff0c;在商店里面可以直接下载安装 http://spark-app.store/ 2.创建文件夹 3.启动VScode并打开该文件夹 4.安装以下几个扩展 PS&#xff1a;Clang这个插件别安装&…

Spark 应用程序优化和调优总结

文章目录 前言调整 Spark 默认配置查看和设置 Spark 配置信息动态扩展集群负载 数据的缓存和持久化DataFrame.cache()DataFrame.persist()何时缓存和持久化何时不缓存和持久化 Spark 中的 JOINs广播连接排序合并连接 总结 前言 本文总结了 Spark 中比较重要和常用的调优手段&a…

docker pull镜像的时候指定arm平台

指定arm平台 x86平台下载arm平台的镜像包 以mysql镜像为例 docker pull --platform linux/arm64 mysqldocker images查看镜像信息 要查看Docker镜像的信息&#xff0c;可以使用docker inspect命令。这个命令会返回镜像的详细信息&#xff0c;包括其元数据和配置。 docker i…

【重磅推荐】2024七大零售行业线下开店超全指南大全共452份

如需下载完整PPTX可编辑源文件&#xff0c;请前往星球获取&#xff1a;https://t.zsxq.com/19F4dDDrv 联华快客便利店的加盟手册.docx 好德便利店加盟手册.docx 超市&便利店守则:商品退换货管理.docx 赠品管理制度.doc 选址必看.doc 新人续签考核作业.doc 物流箱管理制度.d…

AugmentedReality之路-平面检测(5)

本文介绍通过AR检测水平平面和垂直平面&#xff0c;并将检测到的平面转化为Mesh 1、在首页添加功能入口 在首页添加一个按钮&#xff0c;命名为Start World Track 2、自定义ExecStartAREvent 创建ARSessionConfig并取名为ARSessionConfig_World 自定义ExecStartAREvent&…

C++ | Leetcode C++题解之第20题有效的括号

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isValid(string s) {int n s.size();if (n % 2 1) {return false;}unordered_map<char, char> pairs {{), (},{], [},{}, {}};stack<char> stk;for (char ch: s) {if (pairs.count(ch)) {if (…

SSH穿透ECS访问内网RDS数据库

处于安全考虑&#xff0c;RDS一般只会允许指定的IP进行访问&#xff0c;而我们开发环境的IP往往是动态的&#xff0c;每次IP变动都需要去修改RDS的白名单&#xff0c;为我们的工作带来很大的不便。 那么如何去解决这个问题&#xff1f; 假如我们有一台ESC服务器&#xff0c;E…

DVWA -File Upload-通关教程-完结

DVWA -File Upload-通关教程-完结 文章目录 DVWA -File Upload-通关教程-完结页面功能LowMediumHighImpossible 页面功能 此页面的功能为选择某个图片文件点击Upload按钮上传&#xff0c;上传成功后得知文件上传路径为DVWA\hackable\uploads。 Low 源码审计 这段 PHP 代码…

双云及多云融合(混合云)

背景&#xff1a;客户对于业务的高可用需求&#xff0c;当发生故障时&#xff0c;业务还能正常使用&#xff0c;如某云机房整体宕机&#xff0c;或云管理服务整体宕掉&#xff0c;导致客户业务不可用&#xff0c;此时&#xff0c;需有业务能顺利切换到灾备云上。 需求&#xf…

【八股】AOP

AOP(Aspect Oriented Programming)&#xff0c;面向切面编程&#xff0c;他是一种编程范式。 作用&#xff1a; 在不改变原始设计的的基础上对其进行功能增强。 几个基本概念&#xff1a; 连接点&#xff1a;所有的方法 切入点&#xff1a;追加功能的方法 通知&#xff1a;追加…