P11647 【MX-X8-T6】「TAOI-3」俄罗斯蓝猫 题解

news/2025/2/1 14:54:43/文章来源:https://www.cnblogs.com/Scarab/p/18696296

Description

\(n\)\([0, 10^{18}]\) 之间随机的整数。可以提出两次询问,每次询问给出不超过 \(n-1\) 个二元组 \((x_i,y_i)\)。返回 \(a_{x_i}+a_{y_i}\) 从小到大排序的结果。

不能询问 \((i,i)\) 或者重复的无序对 \((i,j)\)

要求按顺序返回这 \(n\) 个数。\(1\leq n\leq 500\)

Solution

注意到 \(n\) 比较小,值域很大且随机,所以在询问得到可以大致通过加减操作确定其是什么,并且正确率很高。设 \(s(i,j)=a_i+a_j\)

首先考虑如果知道 \(a_1,a_2\),怎么推出后面的数。

注意到 \(s(i-1,i)-s(2,i)=a_{i-1}-a_2\),所以如果已经推出 \(a_1,a_2,\ldots,a_{i-1}\),可以通过询问 \(\left\{(1,2),(2,3),\ldots,(n-1,n)\right\}\)\(\left\{(2,3),(2,4),\ldots,(2,n-1)\right\}\) 并从中暴力枚举出满足条件的 \(s(i-1,i)\)\(s(2,i)\),然后就可以通过 \(s(i-1,i)\)\(a_{i-1}\) 来求出 \(a_i\)


那么怎么知道一部分数的值呢。

由于上面的那个做法已经把两次询问都用上了,所以只能并行地去做一些询问来得到 \(a_1,a_2\)

考虑确定前 \(4\) 个数。

先询问 \(\left\{(1,2),(1,3),(1,4),(4,5),(5,6),\ldots,(n-1,n)\right\}\)\(\left\{(2,3),(3,4),(2,4),(2,5),(2,6),\ldots,(2,n)\right\}\)

通过首先由于 \(s(1,2)+s(3,4)=s(1,3)+s(2,4)=s(1,4)+s(2,3)\),这里有 \(3\) 个相等的和,次数一定是最多的,所以可以以此求出 \(\left\{s(1,2),s(1,3),s(1,4)\right\}\)\(\left\{s(2,3),s(3,4),s(2,4)\right\}\),然后就可以得到 \(a_1\)\(\left\{a_2,a_3,a_4\right\}\)。同时通过之前的 \((4,5)\)\((2,5)\) 可以得到 \(a_4-a_2\),所以可以以很大的概率确定 \(a_2,a_3,a_4\) 分别是哪个。

然后用上面的做法就可以得到后面的数了。

时间复杂度:\(O(n^3)\)

Code

#include <bits/stdc++.h>#ifdef ORZXKR
#include "grader.cpp"
#endifusing i64 = long long;std::vector<i64> game(int n);
std::vector<i64> ask(std::vector<int> x,std::vector<int> y);std::vector<int> work(std::vector<int> vec) {for (auto &x : vec) --x;return vec;
}void del(std::vector<i64> &vec, i64 x) {std::vector<i64> ret;for (auto xx : vec)if (xx != x)ret.emplace_back(xx);vec = ret;
}std::pair<i64, i64> getpr(std::vector<i64> &vec1, std::vector<i64> &vec2, i64 x) {for (auto a : vec1)for (auto b : vec2)if (a - b == x)return {a, b};return {-1, -1};
}std::vector<i64> game(int n) {std::vector<i64> arr(n), res1, res2;std::vector<int> vec1, vec2, vec3, vec4;vec1 = {1, 1, 1}, vec2 = {2, 3, 4};for (int i = 4; i <= n - 1; ++i) vec1.emplace_back(i), vec2.emplace_back(i + 1);vec3 = {2, 3, 4}, vec4 = {3, 4, 2};for (int i = 5; i <= n; ++i) vec3.emplace_back(2), vec4.emplace_back(i);res1 = ask(work(vec1), work(vec2)), res2 = ask(work(vec3), work(vec4));// get a[1] and {a[2], a[3], a[4]}std::map<i64, std::vector<std::pair<i64, i64>>> mp;for (auto x : res1)for (auto y : res2)mp[x + y].emplace_back(x, y);std::vector<i64> v234;i64 mxv = -1, cc = 0;for (auto [x, vec] : mp) {if (vec.size() > cc) {mxv = x, cc = vec.size();}}i64 sum234 = 0;for (auto [x, y] : mp[mxv])arr[0] += x, sum234 += y, del(res1, x), del(res2, y);assert(sum234 % 2 == 0);sum234 /= 2;assert(arr[0] >= sum234 && (arr[0] - sum234) % 3 == 0);arr[0] = (arr[0] - sum234) / 3;for (auto [x, y] : mp[mxv]) v234.emplace_back(x - arr[0]);for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (i == j) continue;auto pr = getpr(res1, res2, v234[i] - v234[j]);if (pr != std::pair<i64, i64>{-1, -1}) {arr[3] = v234[i], arr[1] = v234[j], arr[2] = v234[3 - i - j];}}}// std::cerr << arr[0] << ' ' << arr[1] << ' ' << arr[2] << ' ' << arr[3] << ' ';for (int i = 4; i < n; ++i) {auto pr = getpr(res1, res2, arr[i - 1] - arr[1]);// assert(pr != std::pair<i64, i64>{-1, -1});// assert(pr.first != -1 && pr.second != -1);del(res1, pr.first), del(res2, pr.second);arr[i] = pr.first - arr[i - 1];// std::cerr << arr[i] << ' ';}// std::cerr << '\n';return arr;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式事务之2PC两阶段提交

1. 分布式事务概述 1.1 问题背景 在分布式系统中,业务操作可能跨越多个服务或数据库(如订单服务、库存服务、支付服务),传统单机事务(ACID)无法满足跨网络节点的数据一致性需求。网络不可靠:服务间调用可能失败或超时。 数据一致性:不同节点间的状态需最终一致。 性能与…

【SQL】存储过程、函数、触发器

存储过程 存储过程(Stored Procedure)是一种在数据库中保存的SQL语句集合,它可以执行一系列的数据库操作,例如插入、更新、查询等。存储过程可以提高数据库操作的效率,减少网络流量,并且可以封装复杂的逻辑。定义: 存储过程是一组为了完成特定功能的SQL语句集,这些语句…

[Tools] GitHub Action 部署文档网站

关于部署网站,理论上来讲,只要你有一个服务器,你要采用什么样的方式来部署都是可以的。但是前提是你需要有一个服务器(物理机、云服务器)。 这节课我们部署文档网站选择使用 github 来进行部署,因为 GitHub 为我们提供了一个免费的服务器,一个账号只有一个,只要你在 Gi…

[Tools] VitePress搭建文档网站

创建 API 文档可以选择如下的 3 种方式:功能较少,可以直接写在 README.md 文件里面 内容较多,可以单独写一个文件 API 数量众多(Vue、React 这种级别),需要考虑单独拿一个网站来做详细的文档支持这里我们要搭建的网站实际上就是一个文档网站,这个时候我们可以选择静态站…

[Tools] 搭建文档网站

创建 API 文档可以选择如下的 3 种方式:功能较少,可以直接写在 README.md 文件里面 内容较多,可以单独写一个文件 API 数量众多(Vue、React 这种级别),需要考虑单独拿一个网站来做详细的文档支持这里我们要搭建的网站实际上就是一个文档网站,这个时候我们可以选择静态站…

java中的HsahMap

HsahMap HashMap 是 Java 中最常用的集合类之一,它实现了 Map 接口,基于哈希表存储键值对 HashMap的存储是无顺序的 HashMap存储的是键值对(key-value)其中键key是唯一的,值(value)可以重复。 HashMap的底层是数组和链表 HashMap的常见方法 添加方法: 1,put(K key, V valu…

MyBatis的增删改查实现

首先还是使用上一篇文章相同的数据表和实体类,如下图所示1 package com.loubin.pojo;2 3 public class User {4 private int id;5 private String name;6 private String pwd;7 8 public int getId() {9 return id; 10 } 11 12 public void …

Reqable:现代化 API 调试工具

Reqable 是一款专为开发者设计的现代化 API 调试工具,旨在简化 API 开发、测试和调试的流程。 它支持多种协议(如 HTTP、HTTPS、WebSocket 等),并提供了丰富的功能,帮助开发者更高效地构建、调试和分析 API 请求与响应。 Reqable 以其简洁的设计、强大的功能和卓越的性能,…

DeepSeek-R1?别信新闻,它真能打败 OpenAI?

Yy DeepSeek-R1?别信新闻 它真的是那个打败 OpenAI 的开源黑马模型,还是又一条假新闻? Fabio Matricardi它真的那么厉害……是在哪方面? 前言:DeepSeek在大模型小型以及优化的道路上探索蒸馏和纯强化学习的路径获得的一点成绩确实让美国人紧张了一把,但同时也招致了更严格…

6.演讲比赛流程管理系统

基于STL的演讲比赛流程管理系统。1.需求2.文件目录3.代码 3.1Speaker.h #pragma once #include<iostream> using namespace std;class Speaker {public:string m_Name;double m_Score[2];};3.2SpeechManager.h #pragma once #include<iostream> #include<vector…