求助 splay 样例没过
查看原帖
求助 splay 样例没过
147441
Godzilla楼主2021/11/29 21:58
#include <bits/stdc++.h>

#define LL long long
#define DB double
#define PR pair <int, int>
#define MK make_pair
#define fi first
#define se second
#define pb push_back

using namespace std;

const int kN = 1e5 + 5, kInf = 2e9;

int n, rt;
PR a[kN];

struct Spy {
  int s[kN][2], mn[kN], num[kN], f[kN], val[kN], siz[kN]; bool tag[kN];
#define s(p, k) s[p][k]

  void Update(int p) {
    mn[p] = num[p], siz[p] = 1;
    if (s(p, 0)) mn[p] = min(mn[p], mn[s(p, 0)]), siz[p] += siz[s(p, 0)];
    if (s(p, 1)) mn[p] = min(mn[p], mn[s(p, 1)]), siz[p] += siz[s(p, 1)];
  }

  bool Get(int x) {return s(f[x], 1) == x;}

  void Con(int x, int y, int z) {
    if (x) f[x] = y;
    if (y) s(y, z) = x;
  }
  
  void Rotate(int x) {
    int fa = f[x], ffa = f[fa], m = Get(x), n = Get(fa);
    Con(s(x, m ^ 1), fa, m), Con(fa, x, m ^ 1), Con(x, ffa, n);
    Update(fa), Update(x);
  }
  
  void Build(int l, int r, int fa, int &p) {
    if (l > r) return;
    int mid = (l + r) >> 1; p = mid;
    mn[p] = num[p] = a[mid].fi, val[p] = mid, f[p] = fa, siz[p] = 1;
    if (l == r) return;
    Build(l, mid - 1, p, s(p, 0)), Build(mid + 1, r, p, s(p, 1));
    Update(p);
  }

  void Work(int p) {tag[p] ^= 1;}

  void Pushdown(int p) {if (tag[p]) Work(s(p, 0)), Work(s(p, 1)), swap(s(p, 0), s(p, 1)), tag[p] = 0;}
  
  void Splay(int x, int goal) {
    int q[kN], tot = 0, y = x;
    while (y) q[++tot] = y, y = f[y];
    while (tot) Pushdown(q[tot]), tot--;
    while (f[x] != goal) {
      int fa = f[x];
      if (f[fa] != goal) Rotate(Get(fa) == Get(x) ? fa : x);
      Rotate(x);
    }
    if (!goal) rt = x;
  }
  
  void Split(int l, int r) {
    Splay(l - 1, 0), Splay(r + 1, l - 1), Pushdown(l - 1), Pushdown(r + 1), tag[s(r + 1, 0)] ^= 1;
  }
} T;

int main() {
  scanf("%d", &n);
  for (int i = 2; i <= n + 1; ++i) scanf("%d", &a[i].fi), a[i].se = i;
  a[1] = MK(-kInf, 1), a[n + 2] = MK(kInf, n + 2);
  T.Build(1, n + 2, 0, rt);
  sort(a + 1, a + n + 3);
  for (int i = 2; i <= 2; ++i) {
    T.Splay(a[i].se, 0);
    printf("%d\n", T.siz[T.s(rt, 0)]);
    T.Split(i, T.siz[T.s(rt, 0)] + 1);
  }
  return 0;
}

2021/11/29 21:58
加载中...