zoukankan      html  css  js  c++  java
  • 牛客-Forsaken的数列(Treap)

    题目传送门

    sol:第一次看题还真信了是用线段树来做,但是没什么想法,看了题解发现是我不会的Treap,然后花了几天时间学习了一下并补掉题目

    • 无旋Treap
      #include <bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      const int MAXN = 2e5 + 10;
      struct Treap {
          int ls, rs;
          int rand, size;
          LL sum, val, lazy;
      } node[MAXN];
      int root, tot;
      int add_node(int v) {
          int i = ++tot;
          node[i].ls = node[i].rs = 0;
          node[i].rand = rand();
          node[i].sum = node[i].val = v;
          node[i].lazy = 0;
          node[i].size = 1;
          return i;
      }
      void push_down(int rt) {
          int ls = node[rt].ls;
          int rs = node[rt].rs;
          if (ls != 0) {
              node[ls].lazy += node[rt].lazy;
              node[ls].val += node[rt].lazy;
              node[ls].sum += node[ls].size * node[rt].lazy;
          }
          if (rs != 0) {
              node[rs].lazy += node[rt].lazy;
              node[rs].val += node[rt].lazy;
              node[rs].sum += node[rs].size * node[rt].lazy;
          }
          node[rt].lazy = 0;
      }
      void push_up(int rt) {
          int ls = node[rt].ls;
          int rs = node[rt].rs;
          node[rt].size = node[ls].size + node[rs].size + 1;
          node[rt].sum = node[ls].sum + node[rs].sum + node[rt].val;
      }
      void split(int rt, int& a, int& b, int s) {
          if (rt == 0) {
              a = b = 0;
              return;
          }
          push_down(rt);
          int size = node[node[rt].ls].size;
          if (size < s) {
              a = rt;
              split(node[rt].rs, node[a].rs, b, s - size - 1);
          } else {
              b = rt;
              split(node[rt].ls, a, node[b].ls, s);
          }
          push_up(rt);
      }
      void merge(int& rt, int a, int b) {
          if (a == 0 || b == 0) {
              rt = a + b;
              return;
          }
          push_down(a);
          push_down(b);
          if (node[a].rand < node[b].rand) {
              rt = a;
              merge(node[rt].rs, node[a].rs, b);
          } else {
              rt = b;
              merge(node[rt].ls, a, node[b].ls);
          }
          push_up(rt);
      }
      void insert(int p, int v) {
          int x = 0, y = 0;
          split(root, x, y, p - 1);
          merge(root, x, add_node(v));
          merge(root, root, y);
      }
      void add(int l, int r, int v) {
          int x = 0, y = 0, z = 0;
          split(root, root, z, r);
          split(root, x, y, l - 1);
          node[y].lazy += v;
          node[y].val += v;
          node[y].sum += node[y].size * v;
          merge(root, x, y);
          merge(root, root, z);
      }
      LL query(int l, int r) {
          int x = 0, y = 0, z = 0;
          split(root, root, z, r);
          split(root, x, y, l - 1);
          LL sum = node[y].sum;
          merge(root, x, y);
          merge(root, root, z);
          return sum;
      }
      int main() {
          int n, q;
          scanf("%d", &n);
          for (int i = 1; i <= n; i++) {
              int v; scanf("%d", &v);
              merge(root, root, add_node(v));
          }
          scanf("%d", &q);
          for (int i = 1; i <= q; i++) {
              int opt; scanf("%d", &opt);
              if (opt == 1) {
                  int pos; scanf("%d", &pos);
                  insert(pos, 0);
              } else if (opt == 2) {
                  int l, r, v;
                  scanf("%d%d%d", &l, &r, &v);
                  add(l, r, v);
              } else {
                  int l, r;
                  scanf("%d%d", &l, &r);
                  printf("%lld
      ", query(l, r));
              }
          }
          return 0;
      }

      在前置知识都掌握的情况下Treap还是挺好懂的,而且之前感觉lazy标记挺乱的,看了这题之后感觉理清了

  • 相关阅读:
    C++ P1890 gcd区间
    C++ P1372 又是毕业季I
    C++ CF822A I'm bored with life
    C++ P4057 [Code+#1]晨跑
    C++ CF119A Epic Game
    关于树状数组的几点总结
    markdown语法
    portal开发"下拉框"“日期框”查询要怎么配置
    泛型总结--待续
    Actioncontext跟ServletActionContext的区别---未完待续
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/11803932.html
Copyright © 2011-2022 走看看