我正在尝试解决此代码问题
http://codeforces.com/contest/281/problem/D
给定一个整数数组,找到任何子序列中第一个和第二个最大元素的最大xor?
我无法找出解决此问题的最佳方法。我所阐述的解决方法很少使用排序,堆栈,但我无法找到正确的解决方案。
我用Google搜索并找到问题设定者的解决方案代码。但我无法理解解决方案,因为它在c ++中并且我很天真。
以下是c ++中问题设定者的代码
using namespace std;
using namespace io;
typedef set<int> Set;
typedef set<int, greater<int> > SetRev;
namespace solution {
const int SIZE = 100000 + 11;
int n;
int A[SIZE];
II S[SIZE];
Set P;
SetRev P_rev;
int result;
}
namespace solution {
class Solver {
public:
void solve() {
normalize();
result = get_maximum_xor();
}
int get_maximum_xor() {
int res = 0;
for (int i = 0; i < n; i++) {
int current_value = S[i].first;
Set::iterator it_after = P.upper_bound(S[i].second);
Set::iterator it_before = P_rev.upper_bound(S[i].second);
if (it_after != P.end()) {
int after_value = A[*it_after];
res = max(res, current_value ^ after_value);
}
if (it_before != P_rev.end()) {
int before_value = A[*it_before];
res = max(res, current_value, before_value);
}
P.insert(S[i].second);
P_rev.insert(S[i].second);
}
return res;
}
void normalise() {
for (int i = 0; i < n; i++) {
S[i] = II(A[i], i);
}
sort(S, S + n, greater<II>());
}
}
有人可以向我解释一下解决方案,这个方法是我理解的,而不是完全理解的吗?
答案 0 :(得分:1)
好的,所以Solver::solve()
首先调用normalise
:
void normalise() {
for (int i = 0; i < n; i++) {
S[i] = II(A[i], i);
}
sort(S, S + n, greater<II>());
}
正在做的是整数A
整数 - 比如{4, 2, 9}
,并填充数组S
A
的值排序并与它们在A
中显示的索引配对 - 例如{{2, 1}, {4, 0}, {9, 2}}
。
然后解算器调用get_maximum_xor()
...
for (int i = 0; i < n; i++) {
int current_value = S[i].first;
Set::iterator it_after = P.upper_bound(S[i].second);
Set::iterator it_before = P_rev.upper_bound(S[i].second);
&#34; for i&#34; loop用于从S
获取连续的排序值(这些值最初来自A
)。虽然您还没有发布完整的程序,但我们无法确定在P
中没有预先填充任何值,我会假设这一点。我们知道P
是std::map
和upper_bound
次搜索,以查找P
中大于S[i].second
的第一个元素(索引所在的位置) current_value
中出现了A
以及上面的值,然后是P_rev
的类似内容std::map
,其中值按降序排序,可能会保持填充与P
相同的值,但我们也没有代码。
则...
if (it_after != P.end()) {
int after_value = A[*it_after];
res = max(res, current_value ^ after_value);
}
...说如果P
中的任何值都是>=
S[i].second
,请在找到的索引A
处查找it_after
(获取现在感觉P
跟踪每个子序列中的最后一个元素(?)),并且current_value
与来自A
的值的res
XORed是否超过任何先前的结果候选({{1}然后使用新的更大值更新res
。
它与P_rev
类似。
...最后
P.insert(S[i].second);
P_rev.insert(S[i].second);
将current_value
中的A
索引添加到P
和P_rev
以供将来迭代使用。
所以,虽然我还没有解释算法的工作原理或方法(我甚至没有读过问题陈述),但我认为应该清楚说明C ++正在做什么,这就是你所说的你正在努力 - 你自己完成其余的事情; - )。