【备战秋招】每日一题:4月1日美团春招(二批)第三题:题面+题目思路 + C++/python/js/Go/java带注释

news2024/11/22 14:07:37

2023大厂笔试模拟练习网站(含题解)

www.codefun2000.com
最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据,挂载到我们的OJ上,供大家学习交流,体会笔试难度。现已录入200+道互联网大厂模拟练习题,还在极速更新中。欢迎关注公众号“塔子哥学算法”获取最新消息。
在这里插入图片描述
提交链接:

https://codefun2000.com/p/P1139

为了更好的阅读体检,可以查看OJ上的题解。进入提交链接,点击右边菜单栏的"查看塔子哥的题解"

题目内容

塔子哥是一个热爱收藏的年轻人,他喜欢收集各种有趣的物品,例如邮票、硬币、瓶盖等等。他的收藏品越来越多,于是他决定为自己在收藏架上建了一排 n n n 个收藏夹,分别编号为 1 , 2 , 3 … n 1,2,3…n 1,2,3n。这样,他就可以更好地组织和展示自己的收藏品了。

塔子哥有些时候会突发奇想改变某一个收藏美里的内容,例如从中拿入、拿出一些藏品,这些的操作会改变塔子哥对这个收藏夹的欣赏程度,我们记编号为 i i i 的收藏夹,塔子哥对其的欣赏程度为 a i a_i ai 。塔子哥在休息时间经常会欣赏连续编号的收藏夹,例如编号为 L , L + 1 , L + 2 , . . . , R − 1 , R L,L+1,L+2,...,R-1,R L,L+1,L+2,...,R1,R 的这些收藏夹,他能从中获得的满足感为这些收藏失的欣赏程度之和,即 ∑ i = L R a i \sum ^R _{i=L} a_i i=LRai

塔子哥想在欣赏之前提前估算自己能得到的满足感,想知道如果他选择编号区间为 [ L , R ] [L,R] [L,R] 的收藏夹,能给他带来的满足感是多少。但是塔子哥不想自己计算,所以他想你帮他计算一下,然后告诉他。

输入描述

第一行两个整数 n n n m m m ,表示塔子哥的收藏夹数量和塔子哥的操作数量。初始时刻收藏夹都是空的,也即 a i = 0 a_i = 0 ai=0 i ∈ [ 1 , n ] i \in [1,n] i[1,n]

第二行 m m m 个整数 o p 1 , o p 2 , … , o p m op_1,op_2,…,op_m op1,op2,,opm

第三行 m m m 个整数 x 1 , x 2 , … , x m x_1,x_2,…,x_m x1,x2,,xm

第四行 m m m 个整数 y 1 , y 2 , … , y m y_1,y_2,…,y_m y1,y2,,ym ,这些共同表示了 m m m 次操作,对于第 i i i 次操作, o p i = 0 op_i=0 opi=0 时表示为一次收藏夹更新操作,会将 x i x_i xi 位置的收藏夹欣赏程度更新为 y i y_i yi ,即 a x i = y i a_{x_i} = y_i axi=yi o p i = 1 op_i=1 opi=1 时表示为一次查询操作,表示如果塔子哥欣赏编号在区间 [ x i , y i ] [x_i,y_i] [xi,yi] 的收藏夹,能获得的满足感是多少,也即 ∑ j = x i y i a j \sum^{y_i}_{j=x_i} a_j j=xiyiaj

对于所有的数据, $1\le n,m \le 50000,op_i \in [0,1] $ ,当 o p i = 0 op_i = 0 opi=0 时, 1 ≤ x i ≤ n , 0 ≤ y i ≤ 10000 1\le x_i\le n,0\le y_i \le 10000 1xin,0yi10000 ;当 $op_i = 1 $ 时, 1 ≤ x i ≤ y i ≤ n 1\le x_i \le y_i \le n 1xiyin ,保证至少有一次 o p i = 1 op_i =1 opi=1 的操作。

输出描述

对每一个 o p i = 1 op_i = 1 opi=1 的操作,输出一个数表示对应答案。空格隔开所有答案。

样例

输入

4 7
1 0 1 0 1 0 1
1 1 1 3 1 4 1
3 2 3 5 3 100 3

输出

0 2 7 7

样例解释
操作记录为

0 0 0 0(初始)

询问[1,3]结果为0+0+0>

2 0 0 0<1号更改为2>

<询问[1,3],结果为2+0+0>

2 0 5 0 <3号更改为5>

<询问[1,3]结果为2+0+5>

2 0 5 100<4号更改为100>

<询问[1,3],结果为2+0+5>

题目思路

思路:树状数组模板题

转化题意之后,问题变为:给定一个序列,需要维护两类操作:单点修改值 + 区间查询和 . 这是经典的树状数组(BIT)的应用,简称裸题/模板题。我们可以做到 O ( l o g   n ) O(log\ n) O(log n) 的修改和查询。

没有接触过的同学,塔子哥在此推荐以下几个学习网站:

1.B站视频-完全理解并深入应用树状数组

推荐理由:manim制作,生动形象。UP主是鹤翔万里,OIer佬。现在浙大cs读本科。质量非常高!

2.Oi-Wiki-树状数组

推荐理由:文章质量非常高。有严谨的证明+详尽的代码+例题。此外,其他很多算法上面也有写。刷题必备。

题外话

当时这道题在赛码上是放暴力算法过了。也就是你不用上树状数组,直接模拟就能在笔试中拿满分。但是塔子哥并不推荐去赌出题人会手下留情。

类似题目推荐

leetcode

1.315. 计算右侧小于当前元素的个数

2.327. 区间和的个数

CodeFun2000

P1122 小红书-2023.03.26-第三题-涂色

P1217 华为秋招-2022年10月12日-第二题-幼儿园排队报数

P1053 华东师范大学保研机试-2022-Minimum_Sum

P1131 腾讯春招-2023.03.26-第四题-顺子区间

P1263 塔子月赛1-第二题-2333的超级队列 (树状数组上二分,难度较高!)

代码

C++

#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + 5;
// 树状数组模板
#define lb(x) ((x) & (-x))
int a[N], n, op[N], x[N], y[N];
int get_pre(int i) {
    int ret = 0;
    for (; i > 0;i -= lb(i)) ret += a[i];
    return ret;
}
void modify(int i, int val) {
    for (; i <= n; i += lb(i)) a[i] += val;
}

int get(int l, int r) {
    if (l > r) return 0;
    return get_pre(r) - get_pre(l - 1);
}
// end
int main() {
    int m;
    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        cin >> op[i];
    }
    for (int i = 1; i <= m; ++i) {
        cin >> x[i];
    }
    for (int i = 1; i <= m; ++i) {
        cin >> y[i];
    }
    // 模板,没什么好讲的
    for (int i = 1; i <= m; ++i) {
        if (op[i] == 1) {
            cout << get(x[i], y[i]);
            cout << " ";
        } else {
            int p = get(x[i] , x[i]);
            modify(x[i], -p);
            modify(x[i], y[i]);
        }
    }
    return 0;
}

python

# 树状数组类
class NumArray:
    def __init__(self, nums):
        self.nums = nums
        self.tree = [0] * (len(nums) + 1)
        for i, num in enumerate(nums, 1):
            self.add(i, num)

    # 向树状数组中添加元素
    def add(self, idx, val):
        while idx < len(self.tree):
            self.tree[idx] += val
            idx += (idx & -idx)

    # 计算前缀和
    def preSum(self, idx):
        s = 0
        while idx:
            s += self.tree[idx]
            idx -= (idx & -idx)
        return s

    # 更新nums中的元素,并同步更新树状数组
    def update(self, index: int, val: int) -> None:
        self.add(index + 1, val - self.nums[index]) # 将更新差值加入树状数组中
        self.nums[index] = val # 更新nums中的元素

    # 计算区间和
    def sumRange(self, left: int, right: int) -> int:
        return self.preSum(right+1) - self.preSum(left)

n, m = map(int, input().split())
op = [[0] * m for _ in range(3)]
for i in range(3):
    op[i] = list(map(int, input().split()))

obj = NumArray([0] * n)
for i in range(m):
    if op[0][i] == 0: # 更新操作
        obj.update(op[1][i]-1, op[2][i])
    else: # 区间查询操作
        print(obj.sumRange(op[1][i]-1, op[2][i]-1), end=" ")

Java

import java.util.Scanner;

public class Main {
    static int[] tree; // 树状数组
    static int[] item; // 数组元素
    static int n; // 数组长度

    // 计算x的最后一位1所代表的数值,就是lowbit(x)
    static int lowbit(int x){
        return x & -x;
    }

    // 在树状数组的第x个位置增加u
    static void add(int x,int u){
        for (int i = x; i <= n; i+=lowbit(i)) {
            tree[i]+=u;
        }
    }

    // 查询前缀和,返回[1,x]上所有元素之和
    static int query(int x){
        int res = 0;
        for (int i = x; i >0; i-=lowbit(i)) {
            res+=tree[i];
        }
        return res;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        int m = sc.nextInt();
        int[] op = new int[m]; // 操作代码
        int[] x = new int[m]; // x参数
        int[] y = new int[m]; // y参数
        for (int i = 0; i < m; i++) {
            op[i] = sc.nextInt();
        }
        for (int i = 0; i < m; i++) {
            x[i] = sc.nextInt();
        }
        for (int i = 0; i < m; i++) {
            y[i] = sc.nextInt();
        }
        item = new int[n+1]; // 数组元素
        tree = new int[n+1]; // 树状数组
        for (int i = 1; i <= n; i++) {
            add(i,item[i]); // 初始化树状数组,将item中的元素加入其中
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < m; i++) {
            if(op[i]==0){ // 更新操作
                add(x[i],y[i]-item[x[i]]); // 将tree[x]增加y[i]-item[x[i]],相当于更新差值
                item[x[i]] = y[i]; // 更新item[x]
            }else { // 区间查询操作
                sb.append(query(y[i])-query(x[i]-1)+ " ");
            }
        }
        System.out.println(sb.toString());
    }
}

Go

package main

import (
    "bufio"
    "fmt"
    "os"
)

var (
    n     int     // 数组长度
    tree  []int   // 树状数组
    item  []int   // 数组元素
    op    []int   // 操作代码
    x     []int   // x参数
    y     []int   // y参数
)

// 计算x的最后一位1所代表的数值,就是lowbit(x)
func lowbit(x int) int {
    return x & -x
}

// 在树状数组的第x个位置增加u
func add(x, u int) {
    for i := x; i <= n; i += lowbit(i) {
        tree[i] += u
    }
}

// 查询前缀和,返回[1,x]上所有元素之和
func query(x int) int {
    res := 0
    for i := x; i > 0; i -= lowbit(i) {
        res += tree[i]
    }
    return res
}

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Fscan(reader, &n)
    var m int
    fmt.Fscan(reader, &m)
    op = make([]int, m)
    x = make([]int, m)
    y = make([]int, m)
    for i := 0; i < m; i++ {
        fmt.Fscan(reader, &op[i])
    }
    for i := 0; i < m; i++ {
        fmt.Fscan(reader, &x[i])
    }
    for i := 0; i < m; i++ {
        fmt.Fscan(reader, &y[i])
    }
    item = make([]int, n+1)
    tree = make([]int, n+1)
    for i := 1; i <= n; i++ {
        add(i, item[i]) // 初始化树状数组,将item中的元素加入其中
    }

    var result string
    for i := 0; i < m; i++ {
        if op[i] == 0 { // 更新操作
            add(x[i], y[i]-item[x[i]]) // 将tree[x]增加y[i]-item[x[i]],相当于更新差值
            item[x[i]] = y[i]           // 更新item[x]
        } else { // 区间查询操作
            result += fmt.Sprintf("%d ", query(y[i])-query(x[i]-1))
        }
    }
    fmt.Print(result)
}

Js

let input = '';
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.on('data', (data) => {
    input += data;
});
process.stdin.on('end', () => {
    const lines = input.trim().split('\n');
    const n = parseInt(lines[0].trim().split(' ')[0]);
    const m = parseInt(lines[0].trim().split(' ')[1]);

    let op = lines[1].trim().split(' ').map(Number);
    let x = lines[2].trim().split(' ').map(Number);
    let y = lines[3].trim().split(' ').map(Number);

    
    // 接下来是树状数组的模板
    let item = new Array(n+1).fill(0);
    let tree = new Array(n+1).fill(0);
    function lowbit(x){
        return x & -x;
    }
    
    function add(x,u){
        for(let i=x;i<=n;i+=lowbit(i)){
            tree[i] += u;
        }
    }
    
    function query(x){
        let res = 0;
        for(let i=x; i>0;i-=lowbit(i)){
            res += tree[i];
        }
        return res;
    }
	// end
    
    
    let sb = '';
    for(let i=0;i<m;i++){
        if(op[i]==0){ // 更新操作
            add(x[i],y[i]-item[x[i]]); // 将tree[x]增加y[i]-item[x[i]],相当于更新差值
            item[x[i]] = y[i]; // 更新item[x]
        }else { // 区间查询操作
            sb += `${query(y[i])-query(x[i]-1)} `;
        }
    }
    console.log(sb.trim());
});

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

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

相关文章

Electron简单开发

文章目录 1.参考网站2.HelloWold编写2.1新建空文件夹2.2node初始化2.3安装electron依赖2.4添加.gitignore 文件2.5创建main.js文件和index.html2.6运行electron应用 3.打包 接到一个任务&#xff0c;将electron集成到solidworks中&#xff0c;所以记录一下electron的简单操作&a…

【操作系统】05.文件管理

文件管理 文件的属性 文件内部数据的组织 文件之间的组织 操作系统向上层提供功能 创建文件 删除文件 打开文件 关闭文件 读文件 写文件 文件的逻辑结构 无结构文件 有结构文件 顺序文件 文件的物理结构 磁盘块&#xff08;文件块&#xff09; 连续分配 优点 对于机…

操作系统 四、文件管理

文章目录 4.1 文件的逻辑结构4.2 文件目录4.2.1 目录结构4.2.1.1 单级目录结构4.2.1.2 两级目录结构4.2.1.3 多级目录结构4.2.1.4 无环图目录结构 4.2.2 索引结点(FCB的改进) 4.3 文件的物理结构4.3.1 连续分配4.3.2 链接分配4.3.2.1 隐式链接4.3.2.2 显式链接 4.3.3 索引分配 …

稠密点云获取方法(二)

作为高分辨率三维重建的方法之一,从单张图像生成稠密三维点云在计算机视觉领域中一直有着较高的关注度。 以下文献提出了一种针对二维和三维信息融合的方法以解决三维点云稀疏难以检测远处的目标的问题。 Multimodal Virtual Point 3D Detection 该文献提出一种将 RGB 传感器…

【Mysql】| 超详细常见bug及解决方案

目录 一. &#x1f31f; 引入话题二. &#x1f31f; 引出bug1.1 查看bug1.2 Problem Solving2.1 查看bug2.2 Problem Solving3.1 字段长度异常3.2 Problem Solving 三. &#x1f31f; 最后 一. &#x1f31f; 引入话题 MySQL是一款广泛使用的开源数据库管理系统&#xff0c;它…

小白了解Docker容器技术

一、什么是Docker&#x1f451; 有一个最常见的例子来很好的帮我们简单了解Docker容器技术&#xff1a; 当我们在一台计算机中配置好了环境&#xff0c;花费了极大的时间和精力成功开发部署好了一个应用。准备尝试在不同操作系统、不同环境下部署这个应用时&#xff0c;我们需要…

图及其与图相关的算法

⭐️前言⭐️ 本篇文章主要介绍图及其与图相关的算法 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 &#x1f349;博客中涉及源码及博主…

如何在 Rocky Linux 上检查磁盘空间?

在 Rocky Linux 上检查磁盘空间是系统管理和维护的重要任务之一。磁盘空间的监控和管理可以帮助我们及时发现和解决存储空间不足的问题&#xff0c;以确保系统的正常运行。本文将详细介绍在 Rocky Linux 上检查磁盘空间的方法。 方法 1&#xff1a;使用 df 命令 df 命令是 Li…

SOLIDWORKS技巧大全培训教程

1 您可以使用 CTRLTAB 键循环进入在 SolidWorks 中打开的文件。 2 使用方向键可以旋转模型。按 CTRL 键加上方向键可以移动模型。按 ALT 键加上方向键可以将模型沿顺时针或逆时1 您可以使用 CTRLTAB 键循环进入在 SolidWorks 中打开的文件。 2 使用方向键可以旋转模型。按 CTRL…

【CloudCompare教程】012:基于点云数据的测量功能

本文讲解CloudCompare基于点云数据的测量功能,主要有:点云索引、坐标、距离、角度、面积、标签等。 文章目录 一、加载地形点云数据二、基于点云数据的测量功能1. 选择单点并显示信息2. 选择两点并显示分割信息3. 选择三点并显示相关三角形信息4. 定义矩形2D标签5. 保存当前标…

Milvus向量数据库

Milvus vector database 第一章 Milvus概述 Milvus创建于2019年&#xff0c;唯一的目标是&#xff1a;存储、索引和管理由深度神经网络和其他机器学习(ML)模型生成的大量嵌入向量embedding vectors。 存储对象&#xff1a;向量 NOTE&#xff1a;embedding vectors是对非结构…

c#快速入门(下)

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb;Inline和lambda委托和lambda &#x1f449;&#x1f…

上海斯歌荣获中国低代码/零代码行业“卓越影响力厂商奖”

3月19日&#xff0c;在「第三届中国 ISIG 产业智能大会」隆重的颁奖典礼上&#xff0c;上海斯歌被授予“卓越影响力厂商奖”&#xff0c;并入围国内权威咨询机构LowCode低码时代的《2022年中国低代码&零代码行业研究报告》卓越影响力榜单。 「第三届ISIG中国产业智能大会」…

如何编写接口自动化框架系列通过yaml来管理测试用例(四)

本文是接口自动化测试框架系列篇的第四篇 &#xff0c;主要介绍yaml包的使用 。自动化测试的本质是将功能测试用例交给代码去 目录 1. yaml介绍&#xff1f; 2.python中的yaml包 3.项目中使用yaml包 4 项目总结 执行 &#xff0c;测试人员往往是在自动化框架添加对应的测试…

惠普83752B高功率合成扫频器,20 GHz

惠普83752B扫频仪为元器件测试市场带来了卓越的综合性能&#xff0c;在通用台式扫频仪、扫频仪或标量测试应用中&#xff0c;83752B提供了性价比最高的性能。这款扫频仪在保持模拟源速度的同时&#xff0c;提供了卓越的精度和稳定性。全合成CW、步进和科坡扫描模式可在宽带和窄…

QT+OpenGL几何着色器

QTOpenGL几何着色器 本篇完整工程见gitee:QtOpenGL 对应点的tag&#xff0c;由turbolove提供技术支持&#xff0c;您可以关注博主或者私信博主 几何着色器 几何着色器的输入是一个图元&#xff08;如点或者三角形&#xff09;的一组顶点几何着色器可以再顶点发送到下一着色器…

Linux——进程的等待

目录 前言&#xff1a; 一.进程等待 父进程回收子进程信息的相关函数1&#xff1a;wait函数 实验案例1&#xff1a;设置wait函数参数为NULL 实验案例2&#xff1a;wait函数带wstatus参数的案例&#xff1a;当子进程正常运行完退出时 情况3&#xff1a; wait函数带wstatus参数…

Softing“物联网连接和OPC UA通信”系列研讨会

— 免费线上研讨会概览 — 您是否正在为车间应用寻找机器连接&#xff1f;您是否需要为创新的物联网解决方案制定架构决策&#xff1f;或者您是否已经选择了物联网平台&#xff0c;需要连接组件来访问自动化网络中的数据&#xff1f;在Softing线上研讨会中&#xff0c;我们将讨…

JavaScript 进阶 (三)

目录 编程思想 面向过程编程 面向对象编程 构造函数 原型 原型 constructor 属性 对象原型 原型继承 原型链 编程思想 面向过程编程 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次 调用…

Python中的封装、继承与多态

1. 前言 面向对象的三大特性&#xff0c;想必大家肯定是耳熟能详。就是今天要介绍的内容&#xff1a;封装、继承、多态。面向对象的思想都是一样的&#xff0c;这里我用Python进行实现&#xff01; 2. 封装 2.1 什么是封装呢&#xff1f; 封装就是&#xff1a;我写了一个类…