Codeforces Round 888 (Div. 3)F题题解

news2024/9/25 11:22:13

文章目录

  • [Lisa and the Martians](https://codeforces.com/contest/1851/problem/F)
    • 问题建模
    • 问题分析
      • 1.分析给定的运算操作
      • 2.方法1使用Trie树来查找最符合的数
        • 代码
      • 方法2通过性质,排序后找运算的最大值
        • 代码
      • 证明

Lisa and the Martians

在这里插入图片描述在这里插入图片描述

问题建模

​ 给定n个数和k,每个数小于 2 k 2^k 2k,问哪两个数分别与一个小于 2 k 2^k 2k的数x进行异或运算后再进行与运算的值最大,输出这两个数的编号和x。

问题分析

1.分析给定的运算操作

我们由外向内进行分析,运算最外层为两个数进行与运算,只有两个数对应位都为1才能使最终结果的对应位为1。接着考虑更里面一层中,异或上怎么样的x才能使两个数对应位都为1。若两个数相同,则异或的x对应位为0或者1即可让得到的两个数对应位都为1,若不同则无论x的对应位为什么值,都无法使得最终得到的两个数对应位同时为1。则我们需要找两个数其高位到低位的对应位尽可能相同,才能使得最终的运算结果尽可能大。

2.方法1使用Trie树来查找最符合的数

使用01-Trie对于输入的每个数,在已输入数中查找与该数高位尽可能相同的数,然后计算对应的结果,将该数放入Trie中,最终输出最大值对应使用数值的编号和x。

代码

#include<bits/stdc++.h>

#define x first
#define y second
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N = 2e5 + 10, M = N << 6, Mod = 998244353;
int a[N];
int son[M][2],idx;
int cnt[M];
int n,k;

///将x的编号插入到01-Trie中
void insert(int x, int pos) {
    int p = 0;
    ///由高位向低位检索
    for (int i = k - 1; ~i; i--) {
        int &s = son[p][(x >> i) & 1];
        if (!s)  s = ++idx;
        p = s;
    }
    cnt[p]=pos;
}

///检索与x高位尽可能相同的值的编号
int search(int x) {
    int p = 0;
    for (int i = k - 1; ~i; i--) {
        int s =(x>>i)&1;
        if (son[p][s]) {
            p = son[p][s];
        } else p = son[p][!s];
    }
    return cnt[p];
}

void solve() {
    cin >> n >> k;
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
   
    ///初始化01-Trie的起始编号和各个结点
    idx = 0;
    ///0是起始结点,此外每个数有k位,总共有n个数,每个数的每一位为1个结点,则总共有n*k+1个结点
    for (int i = 0; i <= n * k; i++) {
        son[i][0] = son[i][1] =0;
    }

    int ai = -1, aj = -1, ax = -1, ans = -1;
    for (int i = 0; i < n; i++) {
        if (i) {///第一个数插入后,再进行查询操作,否则会查询到未被初始化的索引
            int j = search(a[i]);
            ///计算当前两个元素a[i]和a[j]进行运算后的最终结果
            ///两个元素对应位置若相同则通过异或变成0,然后取反,再将其限制在k位内,就是最终结果
            int nans = (~(a[i] ^ a[j])) & ((1 << k) - 1);
            if (nans > ans) {
                ans = nans;   
                ///ax为当前两个元素进行运算所需的x
                ///结果位最终若为1,两个数对应位一定相同,则其异或值x对应位一定与两个数对应位相反,则通过异或运算结果位于其中一个数可得到x该位对应的值,再将其限制在k位内,就是最终的x
                ai = i, aj = j, ax =(nans^a[i])&((1<<k)-1);
            }
        }
        insert(a[i], i);
    }
    cout <<aj+1  << " " << ai+1  << " " << ax << "\n";
}

int main() {
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}

方法2通过性质,排序后找运算的最大值

因为我们要找高位到低位尽可能相同的两个数,这样运算结果最大,则这样的两个数若做异或运算其结果为最小值。则问题变成了找到两个做异或运算最小的数。而做异或运算最小的两个数,必定是相邻的,因为相邻的数其高位到低位相同的比较多则异或后高位到低位为0的也多,则可以排序所有元素后,计算相邻两个数的异或值找最小的即可。(该性质证明放在最后面。)

代码

#include<bits/stdc++.h>

#define x first
#define y second
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N = 2e5 + 10, M = N << 6, Mod = 998244353;
PII p[N];
bool cmp(PII &p1, PII &p2) {
    return p1.x < p2.x;
}

void solve() {
    int n,k;
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &p[i].x);
        p[i].y=i;
    }
    sort(p+1,p+1+n,cmp);

    int pos=-1,ans=((1<<k)-1);///初始时k位上都为1
    for(int i=2;i<=n;i++){
        int nans=(p[i].x^p[i-1].x);
        if(nans<=ans)    pos=i,ans=nans;
    }

    int ai=p[pos-1].x,aj=p[pos].x;
    int res= (~(ai ^ aj)) & ((1 << k) - 1);///使用方法1中使用的计算方式计算x
    cout <<p[pos-1].y<<" " <<p[pos].y<<" "<<((res^ai)&((1<<k)-1)) <<"\n";
}

int main() {
    int t = 1;
    cin >> t;
    while (t--) solve();
    return 0;
}

证明

证明:min( x ⨁ y x\bigoplus y xy y ⨁ z y\bigoplus z yz )< x ⨁ z x\bigoplus z xz,当x,y,z都为正整数且(x<y<z)

假设最高位到第i+1位,x,y,z都相同,z的第i位为1,x的第i位为0

  1. 若y第i位为1,则有 y ⨁ z y\bigoplus z yz< x ⨁ z x\bigoplus z xz
  2. 若y第i位为0,则有 x ⨁ y x\bigoplus y xy< x ⨁ z x\bigoplus z xz

所证完毕,则通过该证明,可以说明一个数异或值最小的数为异或上其相邻的数。

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

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

相关文章

如何搭建一个口才培训的网站?需要具备哪些条件?

论文题目&#xff1a;如何搭建一个口才培训的网站及所需条件 摘要&#xff1a; 本文探讨了如何搭建一个口才培训的网站&#xff0c;并详细分析了所需的关键条件。口才培训作为一种重要的社交技能&#xff0c;能够帮助人们提升自信和影响力&#xff0c;因此具有广阔的市场前景。…

【yolov5训练报错Wandb wandb.errors.UsageError: api_key not configured (no-tty).】

跑yolov5训练官方代码出现下面的问题&#xff0c;第一个方法就是关闭代理网络vpn&#xff0c;直接运行&#xff0c;阻止数据上传。 D:\anaconda\envs\yolov5\python.exe C:\Users\ljx\Desktop\yoloair-main\yoloair-main\yolov7\train.py YOLOR 2022-11-8 torch 1.8.1cu111…

Nginx 高性能内存池 ----【学习笔记】

跟着这篇文章学习&#xff1a; c代码实现一个高性能内存池&#xff08;超详细版本&#xff09;_c 内存池库_linux大本营的博客-CSDN博客https://blog.csdn.net/qq_40989769/article/details/130874660以及这个视频学习&#xff1a; nginx的内存池_哔哩哔哩_bilibilihttps://w…

TikTok马来西亚站变动,指定物流服务商!

8月2日&#xff0c;据TechinAsia报道&#xff0c;TikTok已将百世快递在马来西亚的子公司BestExpressMalaysia&#xff0c;指定为其在马来西亚的物流服务商。目前&#xff0c;百世快递已在越南、泰国与TikTok展开类似合作。 合作后&#xff0c;百世马来子公司将为TikTokShop卖家…

js去除字符串中特殊字符并将数据转为数组格式

let str今-天-空-气-很-清-新;let liststr.split(-);console.log(list)使用split将特殊字符去除并将数据转为数组

解决vite+vue3项目npm装包失败

报错如下&#xff1a; Failed to remove some directories [ npm WARN cleanup [ npm WARN cleanup D:\\V3Work\\v3project\\node_modules\\vue, npm WARN cleanup [Error: EPERM: operation not permitted, rmdir D:\V3Work\v3project\node_modules\vue\reactivity\…

Spring @Scheduled单线程单实例的坑

文章目录 前言背景验证解决方案 前言 在 Java Spring 项目中经常会用 Scheduled 来实现一些定时任务的场景&#xff0c;有必要了解一些它使用时的问题和内部实现机制。本文是偶然间发现的一个问题&#xff0c;刷新了我的认知&#xff0c;分享给大家。 其他相关文章&#xff1…

Pytorch深度学习-----神经网络之Sequential的详细使用及实战详解

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

产品经理之路:从C端到B端的崭新旅程

理解C端和B端 在我们开始探讨从C端产品经理到B端产品经理的转变之前&#xff0c;我们首先需要理解C端和B端是什么&#xff0c;以及它们之间有什么区别。 C端产品与B端产品的基本区别 C端产品&#xff08;Consumer端产品&#xff09;是面向普通消费者的产品&#xff0c;如社交…

大数据课程F4——HIve的其他操作

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 掌握HIve的join&#xff1b; ⚪ 掌握HIve的查询和排序 ⚪ 掌握HIve的beeline ⚪ 掌握HIve的文件格式 ⚪ 掌握HIve的基本架构 ⚪ 掌握HIve的优化&#xff1b; 一、jo…

一个对象的内存图,两个对象使用同一个方法的内存图

一个对象的内存图 public class Phone {String brand; //品牌double price; //价格String color; //颜色public void call(String who) {System.out.println("给" who "打电话");}public void sendMessage() {System.out.println("群发短信");…

【第一阶段】kotlin的range表达式

range:范围&#xff1a;从哪里到哪里的意思 in:表示在 !in&#xff1a;表示不在 … :表示range表达式 代码示例&#xff1a; fun main() {var num:Int20if(num in 0..9){println("差劲")}else if(num in 10..59){println("不及格")}else if(num in 60..89…

2023年自动化测试已成为标配?一篇彻底打通自动化测试...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 首先我们从招聘岗…

CompletableFuture原理与实践

文章目录 1 为何需要并行加载2 并行加载的实现方式2.1 同步模型2.2 NIO异步模型2.3 为什么会选择CompletableFuture&#xff1f; 3 CompletableFuture使用与原理3.1 CompletableFuture的背景和定义3.1.1 CompletableFuture解决的问题3.1.2 CompletableFuture的定义 3.2 Complet…

Shell脚本学习-for循环结构1

for循环语句主要用于执行次数有限的循环&#xff0c;而不是用于守护进程和无限循环。 语法结构&#xff1a; for 变量名 in 变量取值列表 do指令... done 提示&#xff1a;in 变量值列表 可以省略&#xff0c;省略就相当于 in "$"&#xff0c;也就是使用for i in &…

企业大数据可视化案例专题分享-入门

一、什么是数据可视化&#xff1f; 基本概念&#xff1a;数据可视化是以图示或图形格式表示的数据。让决策者可以看到以直观方式呈现的分析&#xff0c;以便他们可以掌握困难的概念或识别新的模式。借助交互式可视化&#xff0c;可以使用技术深入挖掘图表和图形以获取更多详细…

Java版工程项目管理系统平台+企业工程系统源码+助力工程企业实现数字化管理 em

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程…

IO进程线程第六天(8.3)线程,线程函数+XMind

创建两个线程&#xff1a;其中一个线程拷贝前半部分&#xff0c;另一个线程拷贝后半部分。 只允许开一份资源&#xff0c;且用互斥锁方式实现。 #include<stdio.h> #include<head.h> #include<pthread.h> struct file {int fp; int fq; off_t size; }; pth…

什么?你还没有用过JPA Buddy,那么你工作肯定没5年

1. 概述 JPA Buddy是一个广泛使用的IntelliJ IDEA插件&#xff0c;面向使用JPA数据模型和相关技术&#xff08;如Spring DataJPA&#xff0c;DB版本控制工具&#xff08;Flyway&#xff0c;Liquibase&#xff09;&#xff0c;MapStruct等&#xff09;的新手和有经验的开发人员…

投资圈爆火的文心杯创业大赛,大模型三大趋势值得关注!

“百模大战”打响&#xff0c;掀起大模型领域“创业热潮”。今年5月31日&#xff0c;百度启动“文心杯”创业大赛&#xff08;后简称“大赛”&#xff09;&#xff0c;不到1个月报名时间&#xff0c;吸引近1000个项目激烈角逐&#xff0c;在知名投资人和AI专家的权威评审和层层…