Vampiric Powers, anyone?
题面翻译
题目描述
DIO 意识到星尘十字军已经知道了他的位置,并且即将要来挑战他。为了挫败他们的计划,DIO 要召唤一些替身来迎战。起初,他召唤了 $ n $ 个替身,第 $ i $ 个替身的战斗力为 $ a_i $。依靠他的能力,他可以进行任意次以下操作:
- 设当前的替身数量为 $ m $。
- DIO 选择一个序号 $ i \text{ } ( 1 \le i \le m ) $。
- 接着,DIO 召唤一个新的替身,其序号为 $ m + 1 $,战斗力为 $ a_{m + 1} = a_i \oplus a_{i + 1} \oplus \ldots \oplus a_m $。其中,运算符 $ \oplus $ 表示按位异或。
- 现在,替身总数就变成了 $ m + 1 $。
但对于 DIO 来说,不幸的是,星尘十字军通过隐者之紫的占卜能力,已经知道了他在召唤替身迎战的事情,而且他们也知道初始的 $ n $ 个替身的战斗力。现在,请你帮他们算一算 DIO 召唤的替身的最大可能战斗力(指单个替身的战斗力,并非所有替身战斗力之和)。
输入格式
每个测试点包含多组测试数据。每个测试点的第一行包含一个整数 $ t \text{ } ( 1 \le t \le 10^4 ) $,代表测试数据组数。
每组测试数据的第一行包含一个整数 $ n \text{ } ( 1 \le n \le 10^5 ) $,代表初始的替身数量。
每组测试数据的第二行包含 $ n $ 个整数 $ a_1, a_2, \ldots, a_n \text{ } ( 0 \le a_i < 2^8 ) $,代表每个替身的战斗力。
保证单个测试点内 $ n $ 的总和不超过 $ 10^5 $。
输出格式
对于每组测试数据,在一行内单独输出一个整数,代表 DIO 召唤的替身的最大可能战斗力(指单个替身的战斗力,并非所有替身战斗力之和)。
说明/提示
在第一组测试数据中,其中一种召唤新替身的方式如下:
- 选择 $ i = 4 $,然后,序列 $ a $ 变为 $ [0, 2, 5, 1, 1] $。
- 选择 $ i = 1 $,然后,序列 $ a $ 变为 $ [0, 2, 5, 1, 1, 7] $。$ 7 $ 即为替身的最大可能战斗力。
在第二组测试数据中,DIO 不需要召唤任何新的替身,因为 $ 3 $ 已经是替身的最大可能战斗力。
题目描述
DIO knows that the Stardust Crusaders have determined his location and will be coming to fight him. To foil their plans he decides to send out some Stand users to fight them. Initially, he summoned $ n $ Stand users with him, the $ i $ -th one having a strength of $ a_i $ . Using his vampiric powers, he can do the following as many times as he wishes:
- Let the current number of Stand users be $ m $ .
- DIO chooses an index $ i $ ( $ 1 \le i \le m $ ).
- Then he summons a new Stand user, with index $ m+1 $ and strength given by: $ $$$a_{m+1} = a_i \oplus a_{i+1} \oplus \ldots \oplus a_m, $ $ <p>where the operator $ \\oplus $ denotes the <a href=”https://en.wikipedia.org/wiki/Bitwise_operation#XOR”>bitwise XOR operation</a>. </p></li><li> Now, the number of Stand users becomes $ m+1$$$.
Unfortunately for DIO, by using Hermit Purple’s divination powers, the Crusaders know that he is plotting this, and they also know the strengths of the original Stand users. Help the Crusaders find the maximum possible strength of a Stand user among all possible ways that DIO can summon.
输入格式
Each test contains multiple test cases. The first line contains the number of test cases $ t $ ( $ 1 \le t \le 10\,000 $ ). The description of the test cases follows.
The first line of each test case contains a single integer $ n $ ( $ 1 \le n \le 10^5 $ ) – the number of Stand users initially summoned.
The second line of each test case contains $ n $ integers $ a_1, a_2, \ldots, a_n $ ( $ 0 \le a_i < 2^8 $ ) – the strength of each Stand user.
It is guaranteed that the sum of $ n $ over all test cases does not exceed $ 10^5 $ .
输出格式
For each test case, output a single integer, maximum strength of a Stand user among all possible ways that DIO can summon.
样例 #1
样例输入 #1
3
4
0 2 5 1
3
1 2 3
5
8 2 4 12 1
样例输出 #1
7
3
14
提示
In the first test case, one of the ways to add new Stand users is as follows:
- Choose $ i=n $ . Now, $ a $ becomes $ [0,2,5,1,1] $ .
- Choose $ i=1 $ . Now, $ a $ becomes $ [0,2,5,1,1,7] $ . $ 7 $ is the maximum strength of a Stand user DIO can summon.
In the second test case, DIO does not need to add more Stand users because $ 3 $ is the maximum strength of a Stand user DIO can summon.
题目的本质是求最大连续区间异或和,因为数范围小,所以数字只能在这个范围,在当前数字i,暴力的话枚举i-1~i,i-2~i,i-3~i......但是会超时,如果枚举出现的数字,就不会超时,每一个出现的数字,就是一段连续区间的异或和,不用管他这个区间是哪个,只需要求最大值即可
滚动数组的滚法
const int N = 2e5 + 10;
int a[N];
int dp[2][256];
void solve()
{
memset(dp, 0, sizeof(dp));
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
int t = 0;
dp[0][0] = 1;
int ans = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= 255; j++)
{
if (dp[t][j])
{
dp[1 - t][a[i] ^ j] = 1;
ans = max(ans, a[i] ^ j);
dp[t][j] = 0;
}
}
dp[1 - t][0] = 1;
t = 1 - t;
}
cout << ans << '\n';
}
求前缀异或和,在这个前缀再异或一个长度比他小的前缀,就是这个前缀的后缀,即达到了区间的目的
const int N = 2e5 + 10;
int a[N];
int b[N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
map<int, int> p;
p[0] = 1;
for (int i = 1; i <= n; i++) b[i] = b[i - 1] ^ a[i], p[b[i]] = 1;
int ans = 0;
for (int i = 1; i <= n; i++)
{
for (auto q: p)
{
ans = max(ans, b[i] ^ q.first);
}
}
cout << ans << '\n';
}