首页 > 其他分享 >[Yandex Cup 2024 Qual F] Zeroth Rome 题解

[Yandex Cup 2024 Qual F] Zeroth Rome 题解

时间:2024-12-19 20:43:27浏览次数:3  
标签:set Cup 题解 询问 Zeroth 2024 popcount le each

前言

English version of this editorial is provided after the sample code.

题意简述

本题为交互题,你需要猜 \(t\) 个 \([0,2024]\) 间的非负整数 \(x_1,x_2,\ldots,x_t\),可以询问最多 \(15\) 次,每次询问形如“给定一个大小为 \(N(1\le N\le 2025)\) 的集合 \(S\) 满足 \(S\) 的每个元素都是 \([0,2024]\) 间的非负整数,交互库回答每个 \(x_i\) 是否在该集合内”。

注意,你的询问需要一次性全部给出,之后交互库再进行回答。但是,对于每个 \(x_i\),交互库会在最多一个询问上给出错误的回复,而你需要准确地找出每个 \(x_i\)。

题目解法

如果交互库不会给出错误的回复,那么解决问题是简单的:考虑二进制拆位,对于每一位,询问值域中所有该位为 \(1\) 的数构成的集合,如果目标数存在于该集合内,代表目标数的该位为 \(1\),否则为 \(0\)。可以在 \(\lceil\log_2V\rceil\) 次询问内完成。

如果交互库会在最多一个询问上给出错误的回复呢?考虑给 \([0,2024]\) 间每个整数一个独特的“编号”:设整数 \(i\) 的编号为 \(a_i\),如果 \(\forall i\ne j,\mathrm{popcount}(a_i\oplus a_j)\ge 3\)(其中 \(\mathrm{popcount}\) 表示一个整数二进制下 \(1\) 的个数,\(\oplus\) 表示按位异或),那么使用上面的询问方法询问这些编号,一定会得出正确的答案。具体确定答案的方法为,假设询问中得到了一个数 \(x\),那么只要找到唯一一个 \(a_i\) 满足 \(\mathrm{popcount}(a_i\oplus x)\le 1\) 的 \(a_i\),\(i\) 即为答案——可以证明这种编号构造方法能唯一确定答案。

现在的问题即为构造一组这样的 \(a_i\)。我们发现可以从 \(0\) 开始给每个数分配编号,将所有不合法的编号插入一个 std::set,之后找之中没出现过的最小非负整数,将其作为编号分配给下一个整数。用上面的方法进行暴力枚举,发现存在一组构造使得 \(a_i\le 32330\),可以在 \(15\) 次询问内找到答案。

示例代码(C++17)

#include<bits/stdc++.h>
using namespace std;
const int N=2024;
int main(){
  ios::sync_with_stdio(false);
  vector<int> a; set<int> s;
  for(int i=0,x=0;i<=N;i++){
    a.emplace_back(x),s.emplace(x);
    for(int j=0;j<15;j++)
      for(int k=0;k<15;k++)
        s.emplace(x^(1<<j)^(j==k?0:(1<<k)));
    while(s.find(x)!=s.end())x++;
  }
  cerr<<a.back()<<endl;
  for(int i=0;i<=N;i++)
    for(int j=i+1;j<=N;j++)
      assert(__builtin_popcount(a[i]^a[j])>=3);
  int t; cin>>t;
  vector<vector<int> > v(15);
  cout<<"15\n";
  for(int i=0;i<15;i++){
    for(int j=0;j<=N;j++)
      if(a[j]>>i&1)
        v[i].emplace_back(j);
    for(int j:v[i])cout<<j<<' ';
    cout<<endl;
  }
  while(t--){
    int c=0,r=-1;
    for(int i=0;i<15;i++){
      int x; cin>>x;
      if(x)c|=1<<i;
    }
    for(int i=0;i<=N;i++)
      if(__builtin_popcount(a[i]^c)<=1)r=i;
    cout<<r<<endl;
  }
  return 0;
}

English Version

Translated by ChatGPT

Problem

This is an interactive problem, where you need to guess $ t $ non-negative integers $ x_1, x_2, \ldots, x_t $ within the range \([0, 2024]\). You can ask at most \(15\) queries, and each query takes the form: "Given a set $ S $ of size $ N(1\le N\le 2025)$, where every element of $ S $ is a non-negative integer within \([0, 2024]\), does the interactor return whether each $ x_i $ is in this set or not?"

Note that you must provide all the queries at once, after which the interactor will respond. However, for each $ x_i $, the system will give incorrect feedback for at most one query, and your goal is to accurately identify each $ x_i $.

Solution

If the interactor never gave incorrect feedback, the solution would be straightforward: Consider the binary representation of each number. For each bit position, query a set consisting of all numbers in the range whose value in that bit position is \(1\). If the target number belongs to that set, then the corresponding bit is \(1\); otherwise, it is \(0\). This could be done in $ \lceil \log_2 V \rceil $ queries.

However, with the interactor potentially giving an incorrect response for up to one query, we need to take a different approach. We assign a unique "code" to each integer in the range \([0, 2024]\). Let the code for integer $ i $ be $ a_i $, and ensure that for all $ i \neq j $, we have $ \mathrm{popcount}(a_i \oplus a_j) \geq 3 $, where $ \mathrm{popcount} $ denotes the number of \(1\)s in the binary representation of an integer, and $ \oplus $ represents the bitwise XOR operation. By querying these codes in the method described earlier, we can guarantee a correct result.

To determine the answer, suppose we obtain a result $ x $ from the queries. We need to find the unique $ a_i $ such that $ \mathrm{popcount}(a_i \oplus x) \leq 1 $, which will give us the correct $ i $. This method ensures that we can uniquely identify the correct answer.

The problem now becomes constructing such a set of $ a_i $. We can assign codes starting from \(0\), and for each code, insert invalid codes into a std::set. Then, for each subsequent number, assign the smallest non-negative integer that has not yet been used as a code. Using brute force exploration, we find that there exists a set of codes such that $ a_i \leq 32330 $, which allows us to find the answer within \(15\) queries.

标签:set,Cup,题解,询问,Zeroth,2024,popcount,le,each
From: https://www.cnblogs.com/physics212303/p/18617889

相关文章

  • [APC001H] Generalized Insertion Sort 题解
    将\(a_i\)视为放在结点\(i\)上面的球;称位置\(i\)对应的球为\(i\),区别于“位置\(i\)上面的球为\(a_i\)”。考虑树是一条链的时候怎么做(下称链插入方法):此时只需要将这条链上面的球按照编号从上到下排序。这是一个类似插入排序的过程,维护深度最大的的若干个球编号的相对顺......
  • [USACO24OPEN] Grass Segments G 题解
    考虑对于一个区间\([l_i,r_i]\),最少重叠长度为\(k_i\),怎样的区间\([l_j,r_j]\)可以与前者产生贡献;首先\(r_j-l_j\gek_i\),在满足这个条件的情况下需要有\(r_j\gel_i+k_i\landl_j\ler_i-k_i\),这里\(\land\)表示合取,即C++中的\(\mathrm{and}\)。正难则反,考虑用长度\(......
  • 题解:P10483 小猫爬山
    思路第一眼我以为是个背包,但由于是分组,所以有多个缆车,明显不能用背包。我做这题是因为老师要求,那是我们在学深搜减枝,所以我就开始写深搜。这一题实际上是先选一直最重的猫,然后搞个\(sum\)数组,每搞一个新缆车的就下一个下标继续放,如果能放就放,当然也要搞一个能放但不放的。减枝......
  • RHCE环境公共问题解决(9.0)
    关于如何使用远程软件进行连接环境问题查看此处网络适配器模式,如果是NAT请修改为仅主机模式Vmware有两张网卡,一张是Vmware1,一张是Vmware8(环境必须用仅主机,避免环境判分错误)默认情况下,仅主机模式修改Vmware1网卡 打开Windows的网络适配器可以看到两张网卡 环境IP为1......
  • AT_agc030_f [AGC030F] Permutation and Minimum 题解
    先去掉相邻两个都填完的位置,对于两个都没填的记个数为\(c\),最后只需要将答案乘上\(c!\)。接下来考虑从小到大枚举所有数进行dp,记\(f_{i,j,k}\)表示考虑完前\(1\simi\),有\(j\)个数需要跟一个位置确定的数匹配,有\(k\)个数需要跟后面一个自由的数匹配,考虑当前的数:如果......
  • AT_agc009_d [AGC009D] Uninity 题解
    一道妙妙题。一句话题意:求点分树的高度最小值。给所有点填上一个数表示它子树\(k\),考虑一种填法什么时候满足条件,发现当且仅当任意两对值相同的点之间的路径上存在一个权值更大的点。考虑随便找一个点作为根从叶子节点开始贪心填值,每次选择能填的最小值,发现这样填最终的值的最......
  • 题解:最优硬币组合问题
    更多算法题的题解见:算法刷题题解汇总(持续更新中)一、问题背景小C有多种不同面值的硬币,每种硬币的数量是无限的。他希望知道,如何使用最少数量的硬币,凑出给定的总金额N。小C对硬币的组合方式很感兴趣,但他更希望在满足总金额的同时,使用的硬币数量尽可能少。例如:小C有三种硬币......
  • 题解:P11409 西湖有雅座
    题解:P11409西湖有雅座题目转送带简洁思路由于数据比较小,可以先预处理出任何两个零件是否能出现在同一栋大楼上。即枚举所有的两个零件,根据题意去模拟判断条件是否满足:\[\foralli,j\inU,f\left(i,j\right)\ge\lceil\frac{\min\left(S\left(i\right),S\left(j\righ......
  • 把半年前完全没思路的题解了的感觉真好
    虽然处理了很多次索引思路,不过最后还是过了。第一眼就有解题思路,这种感觉真不错,要的就是这种打怪升级的正反馈。附上解题代码`#@lcapp=leetcode.cnid=2266lang=python3[2266]统计打字方案数@lccode=startfromcollectionsimportCounterfromfunctoolsimportcac......
  • CF1100F题解
    \(CF1100F\),\(Ivan\)\(and\)\(Burgers\)题意:静态序列查询一个区间中选取任意个数的最大异或和,\((n\le10^6)\)\(sol\):考虑离线做,把询问按\(r\)从小到大排序,每次\(r\)右移时把新框进来的数加入线性基中,同时记录线性基每一位在序列中的位置,贪心的考虑显然位置越靠后越优,查......