社区讨论

好久没打Splay,模板题去世了。

P4146序列终结者参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi7yzrny
此快照首次捕获于
2025/11/21 05:55
4 个月前
此快照最后确认于
2025/11/21 05:55
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>

// {{{
#define PI pair<int, int>
#define mk make_pair
#define reg register
#define ll long long
#define rep(i, a, b) for(reg int i = a; i <= b; ++i)
#define per(i, a, b) for(reg int i = a; i >= b; --i)
#define ls tree[x].ch[0]
#define rs tree[x].ch[1]
#define F(x) tree[x].fa
#define S(fa, son) tree[fa].ch[son]
#define P(fa, son) (S(fa, 1) == son)
// }}}

using namespace std;

inline int min(reg int a, reg int b) { return a < b ? a : b; }
inline int max(reg int a, reg int b) { return a > b ? a : b; }
inline int read() {
  reg int s = 0, f = 1; reg char ch = getchar();
  while (!isdigit(ch)) { if (ch == '-') f = - 1; ch = getchar(); }
  while (isdigit(ch)) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
  return s * f;
}

#define N 50005

int n, m, root;

class Node {
  public:
    int ch[2], cnt, tag, fa, val, rev, Max;
} tree[N];

inline void reverse(int x) {
  swap(ls, rs);
  tree[ls].rev ^= 1, tree[rs].rev ^= 1;
}

inline void pushup(int x) {
  tree[x].cnt = tree[ls].cnt + tree[rs].cnt + 1;
  tree[x].Max = max(tree[ls].Max, tree[rs].Max);
  tree[x].Max = max(tree[x].Max, tree[x].val);
}

inline void pushdown(int x) {
  if (tree[x].tag != 0) {
    int now = tree[x].tag;
    if (ls) tree[ls].tag += now, tree[ls].Max += now, tree[ls].val += now;
    if (rs) tree[rs].tag += now, tree[rs].Max += now, tree[rs].val += now;
    tree[x].tag = 0;
  }
  if (tree[x].rev) {
    tree[x].rev = 0;
    if (ls) reverse(ls);
    if (rs) reverse(rs);
  }
}

inline void link(int fa, int son, int p) {
  if (fa) S(fa, p) = son;
  if (son) F(son) = fa;
} 

inline void rotate(int x) {
  int y = F(x), z = F(y), p = P(y, x), q = P(z, y), a = S(x, p ^ 1);
  link(y, a, p);
  link(x, y, p ^ 1);
  link(z, x, q);
  pushup(y);
  pushup(x);
}

inline void Splay(int x, int to) {
  while (F(x) != to) {
    int y = F(x), z = F(y);
    if (z != to) rotate(P(z, y) ^ P(y, x) ? x : y);
    rotate(x);
  }
  if (!to) root = x;
}

inline int build(int l, int r, int fa) {
  if (l > r) return 0;
  if (l == r) {
    F(l) = fa;
    tree[l].cnt = 1;
    return l;
  }
  int x = l + r >> 1;
  ls = build(l, x - 1, x);
  rs = build(x + 1, r, x);
  F(x) = fa;
  pushup(x);
  return x;
}

inline int kth(int k) {
  int x = root;
  while (1) {
    pushdown(x);
    if (tree[ls].cnt + 1 < k) {
      k -= tree[ls].cnt + 1;
      x = rs;
    }
    else if (tree[ls].cnt >= k) x = ls;
    else return x;
  }
}

inline int split(int l, int r) {
  l = kth(l), r = kth(r + 2);
  Splay(l, 0), Splay(r, l);
  return S(r, 0);
}

int main() {
  freopen("1.in", "r", stdin);
  freopen("1251.out", "w", stdout);
  n = read(), m = read();
  root = build(1, n + 2, 0); 
  tree[1].val = tree[1].Max = tree[1].tag = -0x7fffffff;
  tree[n + 2].val = tree[n + 2].Max = tree[n + 2].tag = -0x7fffffff;
  rep (i, 1, m) {
    reg int opt = read(), l = read(), r = read();
    if (opt == 1) {
      reg int val = read();
      int now = split(l, r);
      tree[now].tag += val;
      tree[now].val += val;
      tree[now].Max += val;
    }
    if (opt == 2) {
      reverse(split(l, r));
    }
    if (opt == 3) {
      printf("%d\n", tree[split(l, r)].Max);
    }
  }
  return 0; 
}

回复

2 条回复,欢迎继续交流。

正在加载回复...