位运算 离散化 区间和算法

news2024/11/13 16:50:18

目录

  • 一、位运算
    • 1.1 思路
    • 1.1 例题:二进制中1的个数
  • 二、离散化
    • 2.1 概念
    • 2.2 例题:区间和
  • 三、合并区间
    • 3.1 概念
    • 3.2 例题:合并区间

一、位运算

1.1 思路

首先知道一个概念:一个正整数的负数等于其按位取反后+1
-x = ~x + 1
举个例子:3
在这里插入图片描述
而我们通过(x & ~x + 1)或(x & -x)就可以得到二进制数最后一位1的大小。
举个例子:
在这里插入图片描述

1.1 例题:二进制中1的个数

题目链接

题目描述

给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。

输入格式

第一行包含整数 n。
第二行包含 n 个整数,表示整个数列。

输出格式

共一行,包含 n 个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中 1 的个数。

数据范围

1≤n≤100000,
0≤数列中元素的值≤109

输入样例:

5
1 2 3 4 5

输出样例:

1 1 2 1 2

#include<iostream>

using namespace std;

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    int n;
    cin >> n;
    while(n--)
    {
        int x;
        cin >> x;
        int sum = 0;
        while(x)
        {
            x -= lowbit(x);
            sum++;
        }
        cout << sum << " ";
    }
    return 0;
}

二、离散化

2.1 概念

联想之前讲过的计数排序八大排序,你都掌握了吗?,当两个坐标差距非常大的时候,就不好处理了。而离散化就是把这些下标全部聚集在一起。直接看例题:

2.2 例题:区间和

题目链接

题目描述

假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。
现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。
接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。

输入格式

第一行包含两个整数 n 和 m。
接下来 n 行,每行包含两个整数 x 和 c。
再接下来 m 行,每行包含两个整数 l 和 r。

输出格式

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

数据范围

−109≤x≤109,
1≤n,m≤105,
−109≤l≤r≤109,
−10000≤c≤10000

输入样例:

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

输出样例:

8
0
5

思路分析:
下标过于多且可能非常分散,而且是无序且可能重复,那么我们可以把需要用到的下标统计起来,例如(8, 11, 5, 1, 8),然后把他们排序+去重,就得到(1, 5, 8, 11),这样本来需要11个位置存储,现在只需要4个位置就能存住。因为是有序的,所以如果我们要找到下标,就可以用二分查找。
补充一个去重函数:
unique

template <class ForwardIterator>
  ForwardIterator unique (ForwardIterator first, ForwardIterator last);

他会自动去重且把重复的元素排到最后面并且把后边重复下标的第一个位置返回回来。

在这里插入图片描述

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 3e5 + 10;

int a[N], s[N];// a存数据,s存前缀和
vector<int> Index;// 下标
typedef pair<int, int> PII;
vector<PII> add, sum;
// add记录要加的下标及数据
// sum存要加的区间

//通过find找到下标
int find(int x)
{
    int l = 0, r = Index.size() - 1;
    while(l < r)
    {
        int mid = (l + r) >> 1;
        if(Index[mid] >= x)
        {
            r = mid;
        }
        else
        {
            l = mid + 1;
        }
    }
    return r + 1;
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i++)
    {
        int x, c;
        scanf("%d %d", &x, &c);
        add.push_back({x, c});
        Index.push_back(x);
    }
    for(int i = 0; i < m; i++)
    {
        int l, r;
        scanf("%d %d", &l, &r);
        sum.push_back({l, r});
        // 需要的下标也要加上
        Index.push_back(l);
        Index.push_back(r);
    }
    // 排序+去重Index
    sort(Index.begin(), Index.end());
    Index.erase(unique(Index.begin(), Index.end()), Index.end());
    for(int i = 0; i < n; i++)
    {
        a[find(add[i].first)] += add[i].second;
    }
    // 求前缀和
    for(int i = 1; i <= Index.size(); i++)
    {
        s[i] = a[i] + s[i - 1];
    }
    for(int i = 0; i < m; i++)
    {
        int l = find(sum[i].first), r = find(sum[i].second);
        printf("%d\n", s[r] - s[l - 1]);
    }
    return 0;
}

三、合并区间

3.1 概念

在这里插入图片描述
如图,上面三个区间可以合并成两个区间。

3.2 例题:合并区间

题目链接

题目描述

给定 n 个区间 [li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。

输入格式

第一行包含整数 n。
接下来 n 行,每行包含两个整数 l 和 r。

输出格式

共一行,包含一个整数,表示合并区间完成后的区间个数。

数据范围

1≤n≤100000,
−109≤li≤ri≤109

思路分析
我们先把所有区间存起来,再排序,这样每个区间的起始位置就是有序的。那么两个区间的位置关系只有两种情况:
1️⃣ 左区间的end >= 右区间的start,此时就要合并。
2️⃣ 左区间的end < 右区间的start,此时前面的就为一个空间

那么现在我们就可以设置一个start和end来维护当前区间,当是第一种情况时,调整end,start不变。第二种情况start和end都要去维护下一个区间。
要注意的是最后一个区间我们并没有算上,所以结果要+1

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef pair<int, int> PII;
vector<PII> idx;

int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        int l, r;
        scanf("%d %d", &l, &r);
        idx.push_back({l, r});
    }
    sort(idx.begin(), idx.end());
    int start = -1e9 - 10, end = -1e9 - 10;
    int sum = 0;
    for(int i = 0; i < idx.size(); i++)
    {
        if(end != -1e9 - 10 && idx[i].first > end)
        {
            ++sum;
            start = idx[i].first;
            end = idx[i].second;
        }
        else
        {
            end = max(end, idx[i].second);
        }
    }
    ++sum;// 加上最后一段区间
    cout << sum << endl;
    return 0;
}

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

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

相关文章

干货——生产型企业的供应商管理系统模板

供应商管理主要是是通过提高供货产品和服务质量及交付能力&#xff0c;缩短企业采购周期和生产成本&#xff0c;从而提升产品核心竞争力。随着如今信息技术的发展&#xff0c;采用先进的信息化手段更能够提升供应商管控能力&#xff0c;实现资源的有效整合&#xff0c;从而加强…

[附源码]计算机毕业设计疫苗药品批量扫码识别追溯系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

测试服务器的udping值

测试服务器的udping值参考下载工具步骤一&#xff1a;在服务器上启动UDP Echo服务(必须)启动**UDP Echo服务**步骤二&#xff1a;在客户端下载UDPing工具步骤三&#xff1a;在客户端测试UDPing值参考 https://help.aliyun.com/document_detail/158771.html UDPing项目地址: h…

阿里资深架构师整理分享的分布式系统架构:技术栈详解与进阶文档

前言 有人调侃我们说&#xff1a; 程序员不如送外卖。送外卖是搬运食物&#xff0c;自己是搬运代码&#xff0c;都不产出新的东西……透支体力&#xff0c;又消耗健康&#xff0c;可替代性极强&#xff0c;30岁之后就要面临被优化的危险……想跳槽&#xff0c;但是更高的平台…

PyTorch 2.0 重磅发布:一行代码提速 30%

在今天的 PyTorch 2022 开发者大会上&#xff0c;PyTorch 团队发布了一个新特性torch.compile&#xff0c;这个新特性将 PyTorch 的性能推向了新高度&#xff0c;并开始将 PyTorch 的部分实现从 C 中迁移到 Python 中。他们相信这是 PyTorch 一个实质性的新方向--因此称之为 **…

(最优化理论与方法)第六章无约束优化算法-第一节:线搜索方法

文章目录一&#xff1a;无约束优化问题概述二&#xff1a;线搜索方法&#xff08;1&#xff09;概述&#xff08;2&#xff09;线搜索准则A&#xff1a;Armijo准则①&#xff1a;概述②&#xff1a;Armjio准则缺陷③&#xff1a;回退法④&#xff1a;代码B&#xff1a;Goldstei…

从固定管线到可编程管线:十段代码入门OpenGL

文章目录1. 最简单的OpenGL应用程序2. 视点系统和投影矩阵3. 深度缓冲区和深度测试4. 模型的旋转和平移5. VBO和顶点混合数组6. 纹理映射和纹理坐标7. 光照和法向量计算8. 最简单的着色器程序9. 着色器中的MVP矩阵10. 着色器中的漫反射、镜面反射和高光计算1. 最简单的OpenGL应…

【什么是区块链】

区块链技术简介前言一、区块链技术简介二、区块链的特点1.去中心化2.去信任3.不可篡改和伪造4.可溯源5.匿名性三、区块链用到的技术1.非对称密码算法2.哈希函数3.P2P网络4.安全多方计算前言 比特币与区块链的关系&#xff1a; 2008年中本聪&#xff08;Satoshi Nakamoto&…

Python中logging日志模块详解

用Python写代码的时候&#xff0c;在想看的地方写个print xx 就能在控制台上显示打印信息&#xff0c;这样子就能知道它是什么了&#xff0c;但是当我需要看大量的地方或者在一个文件中查看的时候&#xff0c;这时候print就不大方便了&#xff0c;所以Python引入了logging模块来…

104.二叉树的最大深度 | 111.二叉树的最小深度

文章目录二叉树的深度104.二叉树的最大深度题目题解111.二叉树的最小深度题目题解二叉树的深度 104.二叉树的最大深度 题目 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。…

Mac终端常用命令

1、打开窗口命令 快速打开&#xff1a;command空格&#xff08;打开查询&#xff09;&#xff0c;输入ter回车 打开多个窗口&#xff1a;commandN&#xff08;光标在终端执行此操作&#xff09; 2、目录操作 命令名 命令功能 备注 cd 打开当前目录 cd dirname pwd 显示…

Java 调用 Cpp 代码简单示例

Java 调用 Cpp 代码 前言&#xff1a;首先说明一下&#xff0c;本篇文章是干嘛的&#xff0c;简单来说就是在 Java 代码里调用 C 代码。但是呢&#xff0c;这里只做一个简单的示例&#xff0c;调用最简单的 C 代码&#xff0c;起到一个抛砖引玉的作用。如有不对之处&#xff0…

选择编码节点的最佳数量和位置研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

[附源码]计算机毕业设计校园招聘微信小程序Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

代码随想录训练营第39天|LeetCode 62.不同路径、63. 不同路径 II

参考 代码随想录 题目一&#xff1a;LeetCode 62.不同路径 相比于之前的爬楼梯&#xff0c;这题变成了二维&#xff0c;对于某个位置[i,j]&#xff0c;可以从[i-1,j]或者[i,j-1]走到[i,j]&#xff0c;因此在求解思想上其实是类似于爬楼梯的。 确定dp数组及其下标的含义 dp[…

Android Camera性能分析 - 第26讲 DequeueBuffer Latency

本讲是Android Camera性能分析专题的第26讲 ​&#xff0c;我们介绍DequeueBuffer Latency&#xff0c;包括如下内容&#xff1a; DequeueBuffer Latency是什么DequeueBuffer Latency配置DequeeuBuffer Latency实战 视频在线观看&#xff1a; 极客笔记&#xff1a;极客笔记在…

JavaScript正则表达式:正则表达式中的特殊字符

正则表达式的组成 一个正则表达式可以由简单的字符构成&#xff0c;比如 /abc/&#xff0c;也可以是简单和特殊字符的组合&#xff0c;比如 /ab*c/ 。其中特殊字符也被称为元字符&#xff0c;在正则表达式中是具有特殊意义的专用符号&#xff0c;如 ^ 、$ 、 等。 特殊字符非…

logos_HSST简要说明

HSST分为PCS和PMA&#xff0c; TX PCS&#xff1a;8b/10b编码 RX PCS TX PMA RX PMA 含1个HSST&#xff0c;有4个全双工收发LANE。 LINE和PLL的关系 PLL0可以为4个LANE提供时钟&#xff0c;PLL1只能为LANE2&3提供时钟。 PLL VCO 的转出频率范围为 2.125GHz~3.1875GHz。PLL…

【关于Linux中----文件接口、描述符、重定向、系统调用和缓冲区】

文章目录一、C文件接口中的那些事儿二、接口介绍三、文件描述符fd四、重定向五、缓冲区一、C文件接口中的那些事儿 众所周知&#xff0c;Linux是用C语言写成的&#xff0c;那在这篇文章的开头&#xff0c;自然要先对C语言中的文件操作进行一个概括&#xff01; 写文件&#x…

20221203英语学习

今日新词&#xff1a; lecturer n.讲演者, 讲课者, 讲授者, &#xff08;尤指英国大学的&#xff09;讲师 hypothetical adj.假设的, 假定的 rather adv.相当; 宁可, 宁愿; (常用于or后) 更确切些 ring n.戒指, 指环, 环状物; 圆圈; 敲钟, 按铃; 铃声, 钟声 yes adv.(回答…