解决整数数组中的最大xor次要问题

时间:2018-03-24 21:28:46

标签: c++ algorithm sorting xor

我正在尝试解决此代码问题

 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>());
      } 


}

有人可以向我解释一下解决方案,这个方法是我理解的,而不是完全理解的吗?

1 个答案:

答案 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中没有预先填充任何值,我会假设这一点。我们知道Pstd::mapupper_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索引添加到PP_rev以供将来迭代使用。

所以,虽然我还没有解释算法的工作原理或方法(我甚至没有读过问题陈述),但我认为应该清楚说明C ++正在做什么,这就是你所说的你正在努力 - 你自己完成其余的事情; - )。