#luoguP12081. P11635 加强版

    ID: 21689 远端评测题 1000ms 512MiB 尝试: 0 已通过: 0 难度: 7 上传者: 标签>搜索网络流交互题Special Judge剪枝通信题

P11635 加强版

本题没有可用的提交语言。

题目背景

本题较 P11635(CTS 2025 Day 2 T2)添加了 K=8,9,10K = 8, 9, 10 的情形,并提高了 K=6,7K = 6, 7NN 的限制。注意:P11635 的所有 unsigned int 需要修改为 unsigned long long

题目描述

这是一道通信题。

有若干个节点,它们一开始分别存储有一个数字 ai{0,1}a_i \in \{0, 1\},它们想要通过 KK 轮通信知道其它每个节点存储的数字。

每一轮通信开始的时候,每个节点 ii 对每个节点 jj,都会选择一个数字 ci,j{0,1}c_{i,j} \in \{0, 1\},表示它将会向节点 jj 发送数字 ci,jc_{i,j},而在这轮通信结束的时候,节点 jj 会收到所有节点向它发送的数字的和,具体而言节点 jj 会收到一个数字 sj=ici,js_j = \sum_{i} c_{i,j}

现在给定 KK,你需要找到一个尽量大的 NN,满足在通过 KK 轮通信之后每个节点都可以知道所有节点存储的数字。

实现细节

你不需要,也不应该实现 main 函数。

你需要实现以下函数:

  1. int init(int K);

    • 该函数传入通信总轮数 KK 的值。保证 1K101 \leq K \leq 10
    • 该函数需要返回你选择的节点数量 NN你需要保证 1N601 \leq N \leq 60
    • 对于每次代码运行,保证在任意 send 函数调用前,该函数会被交互库调用恰好一次
  2. unsigned long long send(int K, int N, int round, int number, const std::vector<int>& received);

    • 该函数传入通信总轮数 KK,你实现的 init 函数返回的节点数量 NN,当前通信的轮数 round,当前你需要实现的节点的编号 number,当前节点之前通信的轮数中收到的数字 received,其中 received[0] 表示这个节点一开始存储的数字,而 received[i] (1 \leq i < \text{round}) 表示这个节点第 ii 轮通信结束的时候收到的数字。保证 1K101 \leq K \leq 101roundK+11 \leq \text{round} \leq K + 10number<N0 \leq \text{number} < Nreceived 的长度为 round
    • 1roundK1 \leq \text{round} \leq K,你需要返回一个无符号 6464 位整数 xx 表示在这轮通信中节点 number 发送给所有节点的数字,其中 xx 的第 ii 位为节点 number 发送给节点 ii 的数字,高位用 00 补齐。
    • round=K+1\text{round} = K + 1,你需要返回一个无符号 6464 位整数 xx 表示节点 number 经过 KK 轮通信后确定的每个节点存储的数字,其中 xx 的第 ii 位为编号为 ii 的节点存储的数字,高位用 00 补齐。
    • 对于每次代码运行,保证该函数会被交互库调用不超过 10510^5

注意:你需要保证,对于任意两次传入参数相同的函数调用(包括 initsend),返回值也应当相同,否则你的程序将会直接被判定为错误。

题目保证在规定的限制下,交互库在每次代码运行中的运行时间不会超过 100ms100\, \mathrm{ms};交互库使用的内存大小固定,且不超过 64MiB64\, \mathrm{MiB}。这意味着在每次代码运行中你的代码可以使用至少 900ms900\, \mathrm{ms} 的时间和 448MiB448\,\mathrm{MiB} 的空间。

提示

测试程序方式

下发文件中的 grader.cpp 是提供的交互库参考实现,最终测试时所用的交互库实现与该参考实现有所不同,因此你的解法不应该依赖交互库实现。

将你的程序命名为 message.cpp 并放置于下发文件目录下后,你可以在下发文件目录下使用如下命令进行测试:

g++ grader.cpp message.cpp -o grader -std=c++17 -O2
./grader

上述脚本将从标准输入读入以下格式的数据:

  • 输入的第一行一个整数 00
  • 输入的第二行两个正整数 T,KT, K,其中 TT 表示进行通信的次数,KK 表示每次通信的轮数。你需要保证 1T1011 \leq T \leq 1011K101 \leq K \leq 10
  • 输入的第 i+2(0i<T)i + 2 (0 \leq i < T) 行一个无符号 6464 位整数 xix_i,表示第 ii 次通信时每个节点初始存储的数字,其中 xix_i 的第 jj 位表示 jj 号节点初始存储的数字。你需要保证 0i<T,0xi<264\forall 0 \leq i < T, 0 \leq x_i < 2^{64}

上述脚本将输出以下格式的数据到标准输出

  • 若通信结果正确,则输出 Accepted! (N = [N], K = [K])
  • 若通信结果错误,则输出 Wrong answer!

下发文件说明

在下发文件中:

  1. grader.cpp 是提供的交互库参考实现。
  2. template_message.cpp 是提供的示例代码,你可以在此代码的基础上实现。

子任务

本题共有 1010 个子任务,每个子任务分值为 100100 分,总分为 10001000 分。一个子任务的得分为其中所有测试点的得分最小值。

对于所有测试数据,保证 1K101 \leq K \leq 10,且对于每次代码运行,send 会被交互库调用不超过 10510^5 次。对于第 ii 个子任务,保证 K=iK = i

评分方式

注意

  • 你不应当通过非法方式获取交互库的内部信息,如试图直接读取交互库中存储的值,或直接与标准输入、输出流进行交互。此类行为将被视为作弊;
  • 最终的评测交互库与样例交互库的实现有所不同,因此你的解法不应该依赖交互库实现。

本题首先会受到和传统题相同的限制,例如编译错误会导致整道题目得 0 分,运行时错误、超过时间限制、超过空间限制等会导致相应测试点得 0 分等。你只能在程序中访问自己定义的和交互库给出的变量及其对应的内存空间,尝试访问其他空间将可能导致编译错误或运行错误。

在上述条件基础上,在每个测试点中,程序得到的分数将按照以下方式计算:

  • 若对于任意两次传入参数相同的该函数调用,返回值不同,则获得 0 分;
  • KK 轮通信后确定的每个节点存储的数字与每个节点初始存储的数字不同,则获得 0 分;
  • 否则设 NN 为调用函数 init() 得到的结果,则该测试点的得分为 s×0.7max(C(K)N,0)s \times {0.7}^{\max(C(K) - N, 0)},其中 ss 为该测试点的分值,C(K)C(K) 的计算方式如下表所示:
子任务编号 =K== K = C(K)=C(K) =
11 22
22 44
33 66
44 1111
55 1414
66 2222
77 2626
88 3636
99 4141
1010 4747