全部评论 3

  • rmq可以用笛卡尔树解决吗

    2024-12-04 来自 江苏

    1
    • 笛卡尔树比较慢,当然用笛卡尔树也是可以的。经过测试,平均需要 800ms 通过所有的测试点。但使用树状数组/线段树的 RMQ 可以做到平均在 150ms 内通过所有的测试点。

      2024-12-04 来自 加拿大

      1
    • 可以给你提供一个笛卡尔树的代码:

      struct TreapNode {
          int key; // sum[j]
          int priority;
          TreapNode* left;
          TreapNode* right;
      
          // 当前节点的值
          int dp_j_minus_j;
          int dp_j;
          int dp_j_plus_j;
      
          // 子树中的最大值
          int subtree_max_dp_j_minus_j;
          int subtree_max_dp_j;
          int subtree_max_dp_j_plus_j;
      
          TreapNode(int k, int dp_val, int index) : key(k), priority(rand()), left(nullptr), right(nullptr) {
              dp_j_minus_j = dp_val - index;
              dp_j = dp_val;
              dp_j_plus_j = dp_val + index;
      
              subtree_max_dp_j_minus_j = dp_j_minus_j;
              subtree_max_dp_j = dp_j;
              subtree_max_dp_j_plus_j = dp_j_plus_j;
          }
      
          // 更新子树的最大值
          void update() {
              subtree_max_dp_j_minus_j = dp_j_minus_j;
              subtree_max_dp_j = dp_j;
              subtree_max_dp_j_plus_j = dp_j_plus_j;
              if (left) {
                  subtree_max_dp_j_minus_j = max(subtree_max_dp_j_minus_j, left->subtree_max_dp_j_minus_j);
                  subtree_max_dp_j = max(subtree_max_dp_j, left->subtree_max_dp_j);
                  subtree_max_dp_j_plus_j = max(subtree_max_dp_j_plus_j, left->subtree_max_dp_j_plus_j);
              }
              if (right) {
                  subtree_max_dp_j_minus_j = max(subtree_max_dp_j_minus_j, right->subtree_max_dp_j_minus_j);
                  subtree_max_dp_j = max(subtree_max_dp_j, right->subtree_max_dp_j);
                  subtree_max_dp_j_plus_j = max(subtree_max_dp_j_plus_j, right->subtree_max_dp_j_plus_j);
              }
          }
      };
      

      2024-12-04 来自 加拿大

      1
    • struct Treap {
          TreapNode* root;
      
          Treap() : root(nullptr) {}
      
          // 分割 treap,使得左子树所有 key < key_val,右子树所有 key >= key_val
          pair<TreapNode*, TreapNode*> split(TreapNode* node, int key_val) {
              if (!node) return {nullptr, nullptr};
              if (key_val > node->key) {
                  auto split_res = split(node->right, key_val);
                  node->right = split_res.first;
                  node->update();
                  return {node, split_res.second};
              }
              else {
                  auto split_res = split(node->left, key_val);
                  node->left = split_res.second;
                  node->update();
                  return {split_res.first, node};
              }
          }
      
          // 合并两个 treap,所有 keys in left <= keys in right
          TreapNode* merge(TreapNode* left, TreapNode* right) {
              if (!left || !right) return left ? left : right;
              if (left->priority > right->priority) {
                  left->right = merge(left->right, right);
                  left->update();
                  return left;
              }
              else {
                  right->left = merge(left, right->left);
                  right->update();
                  return right;
              }
          }
      
          // 插入一个新的节点
          void insert(int key, int dp_val, int index) {
              TreapNode* new_node = new TreapNode(key, dp_val, index);
              if (!root) {
                  root = new_node;
                  return;
              }
              pair<TreapNode*, TreapNode*> split_res = split(root, key);
              // 处理相同 key 的情况,插入多个相同 key 节点
              root = merge(merge(split_res.first, new_node), split_res.second);
          }
      

      2024-12-04 来自 加拿大

      1
  • 6啊

    2024-12-03 来自 广东

    0
  • 2024-12-03 来自 加拿大

    0
首页