A101466.「联合省选 2024」魔法手杖
NOI/NOI+/CTSC
通过率:0%
时间限制:1.50s
内存限制:1024MB
题目描述
提示: 我们在题目描述的最后提供了一份简要的、形式化描述的题面。
C 城是一座魔力之都,以最高的魔法师水平闻名。对于一名魔法师而言,最重要的固然是魔法手杖和镶嵌在手杖上的魔法水晶。
每个魔法手杖和魔法水晶都可以用魔力值来衡量其能力大小,一个魔法手杖的魔力值是镶嵌在其上的所有魔法水晶中魔力值的最小值。
小 ω 是 C 城的一名见习魔法师,他想加强他的魔法手杖。在加强之前,小 ω 的魔法手杖镶嵌着 n 颗魔法水晶,它们的魔力值分别为 a1,a2,…,an。
小 ω 准备使用一次强力的秘术来加强他的手杖。这一次秘术中,他可以任意选择 x,然后将所有魔法水晶的魔力值由 ai 变为 (ai⊕x),其中 ⊕ 表示按位异或。由于小 ω 能力有限,a1,a2,…,an 和 x 都是 [0,2k−1] 中的整数。
小 ω 还发现这个秘术可以定向加强。具体地,他可以花费 bi 的体力值对第 i 个魔法水晶进行定向加强,将原本应变为 (ai⊕x) 的魔力值变为 (ai+x)。小 ω 能力有限,因此他定向加强所花费的体力值总和不能超过 m,且每个水晶只能被定向加强至多一次。
小 ω 想知道他在加强魔法手杖后,魔法手杖的魔力值最大能为多少,但他并不会算,所以请你来帮他计算。
形式化的: 给定 a1,a2,…,an 以及 b1,b2,…,bn,满足 ai∈[0,2k−1] 以及 bi≥0,你需要给出 S⊆{1,2,…,n} 以及 x∈[0,2k−1] 满足以下条件:
- i∈S∑bi≤m;
- 满足以上条件的前提下,最大化 val(S,x)=min(i∈Smin(ai+x),i∈U\Smin(ai⊕x)) 的值。
你只需要给出最大的 val(S,x) 的值即可。
输入格式
本题有多组测试数据。 输入的第一行包含两个整数 c,T,表示测试点编号与测试数据组数。样例中的 c 表示该样例的数据范围与第 c 个测试点的数据范围相同。
接下来依次给出每组输入数据,对于每组数据:
- 第一行三个整数 n,m,k;
- 第二行 n 个整数 a1,a2,…,an,分别表示每个魔法水晶的初始魔力值;
- 第三行 n 个整数 b1,b2,…,bn,分别表示每个魔法水晶定向加强需要的体力值。
输出格式
对于每组测试数据输出一行一个整数表示小 ω 能获得魔法手杖魔力值的最大值。
输入输出样例
输入#1
1 2 5 2 3 1 1 2 3 7 1 1 0 3 2 1 1 1 1 0
输出#1
5 2
说明/提示
样例解释
【样例 1 解释】
- 对于第一组数据,一种可行的方案为:定向强化魔法水晶 5(即 S={5})并取 x=4,最后得到的魔法水晶魔力值分别为 5,5,6,7,11,故魔法手杖的魔力值为 5。可以证明不存在更优方案。
- 对于第二组数据,一种可行的方案为:定向强化魔法水晶 1(即 S={1})并取 x=1。
数据范围
设 ∑n 表示单组测试点各组数据 n 的和。对于所有测试数据,
- T≥1;
- 1≤n≤105,1≤∑n≤5×105;
- 0≤m≤109;
- 0≤k≤120;
- ∀1≤i≤n,0≤ai<2k;
- ∀1≤i≤n,0≤bi≤109。
复杂度限制
时间限制:1.50s
内存限制:1024.00MB
提示
本题输入文件较大,请使用较为快速的输入方式。
在评测环境中,你可以使用 128 位有符号整数类型 __int128,它可以存储范围在 [−2127,2127−1] 内的整数,使用方法与其他整型类型基本一致。
需要注意,此类型无法使用诸如 cin/cout 或 scanf/printf 等常规输入输出方式进行输入输出。我们在选手目录下提供了一份 __int128 的输入输出函数实现供选手选择使用。
#include<bits/stdc++.h>
using namespace std;
void read(__int128 &x){
// read a __int128 variable
char c; bool f = 0;
while(((c = getchar()) < '0' || c > '9') && c != '-');
if(c == '-'){f = 1; c = getchar();}
x = c - '0';
while((c = getchar()) >= '0' && c <= '9')x = x * 10 + c - '0';
if(f) x = -x;
}
void write(__int128 x){
// print a __int128 variable
if(x < 0){putchar('-'); x = -x;}
if(x > 9)write(x / 10);
putchar(x % 10 + '0');
}
int main(){
__int128 a, b;
read(a);
read(b);
write(a+b);
return 0;
}