暴力+优化
话说网上有字典树的正规解法,不过hdu重现赛时并不会,于是直接暴力了。
优化方式直接在代码注释中标注了,这里不详解了。
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
int a[MAXN];
inline int lowbit(int x)
{
return x & -x;
}
int main()
{
int T; scanf("%d", &T);
while (T--)
{
//input
int n; scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
//sort
sort(a, a + n);
//main
int maxValue = a[n-1] + a[n-2]; //找到最大值
int maxLimit = maxValue;
int ans = 0;
//maxLimit = 小于等于maxValue的最大的2的n次方
//例:若maxValue的二进制表示为11111,则maxLimit为10000
//显然最终的答案一定属于[maxLimit, maxLimit << 1)
while (maxLimit - lowbit(maxLimit) > 0) maxLimit -= lowbit(maxLimit);
//第一种情况
//a[i]+a[j]属于[maxLimit, maxLimit << 1),但a[k]不属于该范围
for (int i = n - 1; i > 0; i--)
for (int j = i - 1; j >= 0; j--)
{
if (a[i] + a[j] < maxLimit) break;
int sum = a[i] + a[j];
int now = maxLimit, kl, kr, num = 0;
//找到sum的第一个0的位置,该位置满足以下条件:
//1.设这个位置为pos,即(1<<pos) & sum = 0
//2.存在a[k],(k != i && k != j),a[k]的二进制的首位也在pos这一位
while (num == 0 && now)
{
while (now && (now & sum)) now >>= 1;
kl = lower_bound(a, a + n, now) - a;
kr = lower_bound(a, a + n, now << 1) - a;
for (int k = kl; k < kr; k++)
{
if (k != i && k != j)
{
num++;
break;
}
}
now >>= 1;
}
//不存在上述位置的情况
if (num == 0)
{
//找到最小的位置且k != i && k != j
int x = 0;
if (x == j) x++;
if (x == i) x++;
//如果最小值为0
if (a[x] == 0)
{
if (sum > ans) ans = sum;
}
else
{
//minLimit = 小于等于a[x]的最大的2的n次方
//则枚举的范围一定在[minLimit, minLimit << 1)之间
int minLimit = a[x];
while (minLimit - lowbit(minLimit) > 0) minLimit -= lowbit(minLimit);
minLimit <<= 1;
for (int k = x; k < n && a[k] < minLimit; k++)
{
if (k != i && k != j && (sum ^ a[k]) > ans) ans = sum ^ a[k];
}
}
}
else
{
//枚举寻找答案
for (int k = kl; k < kr; k++)
{
if (k != i && k != j && (sum ^ a[k]) > ans) ans = sum ^ a[k];
}
}
}
//另外一种情况
//即a[k]属于[maxLimit, maxLimit << 1),但a[i]+a[j]不属于该范围
for (int k = n - 1; k >= 0; k--)
{
if (a[k] < maxLimit) break;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (k != i && k != j && (a[k] ^ (a[i] + a[j])) > ans) ans = a[k] ^ (a[i] + a[j]);
}
}
}
printf("%d\n", ans);
}
return 0;
}