zoukankan      html  css  js  c++  java
  • [Codeforces809D] Hitchhiking in the Baltic States

    给定 (n) 个区间 ([l_i,r_i]) ,整数序列 ({a_n}) 满足 (a_i in [l_i, r_i]),求该序列的最长严格上升子序列的最大长度。

    (1 leq n leq 3 imes 10^5, 1 leq l_i leq r_i leq 10^9)

    (dp[i][j]) 表示在前 (i) 个数中选择一个长度为 (j)LIS,子序列末尾那个数最小是多少。

    由于是严格上升,不难发现 (dp[i][0] < dp[i][1] < dp[i][2] < cdots < dp[i][n])

    忽略第一维,当序列末尾加入一个区间为 ([l,r]) 的数时,分类讨论:

    • 对于满足 (dp[j] < l) 最大的 (j),当前数选择 (l) ,可以用 (l) 更新 (j + 1)
    • 对于 (l leq dp[j] < r),当前数选择 (dp[j] + 1) 就可以更新 (dp[j + 1]),由于单调性,(dp[j] + 1 leq dp[j + 1]),一定可以更新,所以相当于将这段整体右移一位再整体加一。

    由于单调性,这个操作可以用平衡树维护。

    #include <bits/stdc++.h>
    #define dbg(args...) std::cerr << "33[31;1m" << #args << " -> ", err(args)
    inline void err() { std::cerr << "33[0m
    "; }
    template<class T, class... U>
    inline void err(const T &x, const U &... a) { std::cerr << x << ' '; err(a...); }
    
    constexpr int N(3e5 + 5), INF(1e9 + 1);
    
    struct Node {
      Node *ls, *rs;
      int siz, rnd, val, tag;
      inline void pushup() { siz = ls->siz + rs->siz + 1; }
      inline void add(int);
      inline void pushdown() { if (tag) ls->add(tag), rs->add(tag), tag = 0; }
    } t[N], *null = new Node();
    void Node::add(int x) { if (this != null) tag += x, val += x; }
    void split_v(Node *o, int v, Node *&x, Node *&y) {
      if (o == null) {
        x = y = null; return;
      }
      o->pushdown();
      if (v < o->val)
        y = o, split_v(o->ls, v, x, o->ls);
      else
        x = o, split_v(o->rs, v, o->rs, y);
      o->pushup();
    }
    void split_k(Node *o, int k, Node *&x, Node *&y) {
      if (o == null) {
        x = y = null; return;
      }
      o->pushdown();
      if (k <= o->ls->siz)
        y = o, split_k(o->ls, k, x, o->ls);
      else
        x = o, split_k(o->rs, k - o->ls->siz - 1, o->rs, y);
      o->pushup();
    }
    Node* merge(Node *x, Node *y) {
      if (x == null) return y;
      if (y == null) return x;
      x->pushdown(), y->pushdown();
      return x->rnd < y->rnd
        ? (x->rs = merge(x->rs, y), x->pushup(), x)
        : (y->ls = merge(x, y->ls), y->pushup(), y);
    }
    int main() {
      std::ios::sync_with_stdio(false);
      std::cin.tie(nullptr);
      int n; std::cin >> n;
      null->ls = null->rs = null, null->siz = 0, null->val = INF;
      Node *root = null;
      for (int i = 0; i <= n; i++) {
        static std::mt19937 gen(std::chrono::high_resolution_clock().now().time_since_epoch().count());
        t[i].ls = t[i].rs = null;
        t[i].siz = 1, t[i].rnd = gen();
        t[i].val = i ? INF : 0;
        root = merge(root, t + i);
      }
      while (n--) {
        int l, r; std::cin >> l >> r;
        if (l > r) continue;
        Node *a, *b, *c, *d, *o;
        split_v(root, l - 1, a, b);
        split_v(b, r - 1, b, d);
        if (b == null) {
          for (o = d; o->ls != null; o = o->ls) o->pushdown();
          o->val = l;
          root = merge(a, d);
        } else {
          split_k(b, b->siz - 1, b, c);
          for (o = d; o->ls != null; o = o->ls) o->pushdown();
          o->val = std::min(o->val, c->val + 1);
          for (o = b; o->ls != null; o = o->ls) o->pushdown();
          c->val = std::min(l, o->val);
          b->add(1);
          root = merge(merge(a, c), merge(b, d));
        }
      }
      Node *a, *b;
      split_v(root, INF - 1, a, b);
      std::cout << a->siz - 1 << "
    ";
      return 0;
    }
    
  • 相关阅读:
    6. Flask请求和响应
    5. Flask模板
    FW:Software Testing
    What is the difference between modified duration, effective duration and duration?
    How to push master to QA branch in GIT
    FTPS Firewall
    Query performance optimization of Vertica
    (Forward)5 Public Speaking Tips That'll Prepare You for Any Interview
    (转)The remote certificate is invalid according to the validation procedure
    Change
  • 原文地址:https://www.cnblogs.com/HolyK/p/14149054.html
Copyright © 2011-2022 走看看