题解:P13684 【MX-X16-T2】「DLESS-3」XOR and Multiply
题解:P13684 【MX-X16-T2】「DLESS-3」XOR and Multiply
题目思路
异或运算:对于 \(x \oplus y\),若 \(x\) 和 \(y\) 的第 \(i\) 位相同,则返回 \(0\),否则返回 \(1\)。
构造 \((x \oplus z)\) 和 \((y \oplus z)\) 的最大乘积。
令 \(a=x \oplus z\),\(b=y \oplus z\),\(f=x \oplus y\),现在我们尽可能的增大 \(a \cdot b\) 即可。
我们可以从最高位逐位构造。提取每位 \(i\) 的值,将 \(i\) 与 \(f\) 进行按位与运算。若 \(i \mid f=1\),则 \(x\) 与 \(y\) 在这个数位上不同。这里要记录最高位的 \(x\) 与 \(y\) 不同的数位的位置。因为数位越高权值越大,所以这里我们最大化 \(a\) 的贡献,即令 \(a\) 在这个地方位 \(1\),\(b\) 为 \(0\)。对应的,在其他的 \(b\) 的数位上令其为 \(1\) 来增大 \(b\) 的值。
若 \(i \mid f=0\),显然此时 \(x\) 与 \(y\) 在这个数位上相同。这时令其为 \(1\) 即可最大化贡献。
代码实现
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll T,x,y,h;
ll read() {
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
int main() {
T=read();
while (T--){
x=read(),y=read(),h=read();
ll f=x^y;
ll a=0,b=0;
bool flag=false;
for(int i=h-1;i>=0;i--){
ll m=1LL<<i;
if(f&m){
if(!flag) a|=m,flag=true;
else b|=m;
}
else a|=m,b|=m;
}
cout<<a*b<<"\n";
}
return 0;
}
时间复杂度 \(O(T \cdot h)\)。