为什么全M/T
查看原帖
为什么全M/T
124314
lcyxds楼主2021/3/22 17:57
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>

using namespace std;

const int MAXN = 5e5+10;

struct Node{
  int ch[2];
  int fa;
  int randd;
  int size;
};

int n, m;
int list[MAXN];
Node tree[MAXN];
int root;

int Pushup(int p) {
  tree[p].size = tree[tree[p].ch[0]].size+tree[tree[p].ch[1]].size+1;
}

bool Get(int p) {
  return tree[tree[p].fa].ch[1]==p;
}

int Rank(int x) {
  int res = tree[tree[x].ch[0]].size;
  int p;
  bool get;
  while (p = tree[x].fa) {
    //cout << p << endl;
    if (Get(x)) {
      res+=tree[tree[p].ch[0]].size+1;
    }
    x = p;
  }
  //cout << res << endl;
  return res;
}

void Split(int p, int size, int& x, int& y) {
  if (!p) {
    x = y = 0;
    return;
  }
  int l = tree[p].ch[0];
  int r = tree[p].ch[1];
  int lsize = tree[l].size;
  if (size <= lsize) {
    Split(l, size, x, tree[p].ch[0]);
    tree[x].fa = 0;
    tree[tree[p].ch[0]].fa = p;
    Pushup(p);
    y = p;
    return;
  }
  Split(r, size-lsize-1, tree[p].ch[1], y);
  tree[y].fa = 0;
  tree[tree[p].ch[1]].fa = p;
  Pushup(p);
  x = p;
  return;
}

int Merge(int a, int b) {
  //cout << a << ',' << b << endl;
  if (!a) return b;
  if (!b) return a;
  if (tree[a].randd < tree[b].randd) {
    tree[b].ch[0] = Merge(a, tree[b].ch[0]);
    Pushup(b);
    tree[tree[b].ch[0]].fa = b;
    return b;
  }
  tree[a].ch[1] = Merge(tree[a].ch[1], b);
  Pushup(a);
  tree[tree[a].ch[1]].fa = a;
  return a;
}

int Gen(int l, int r, int fa) {
  if (l > r) return 0;
  int mid = l+r>>1;
  int val = list[mid];
  tree[val].fa = fa;
  tree[val].ch[0] = Gen(l, mid-1, val);
  tree[val].ch[1] = Gen(mid+1, r, val);
  tree[val].randd = rand();
  Pushup(val);
  //cout << val << ',' << tree[val].fa << ',' << tree[val].size << endl;
  return val;
}

void Top(int t) {
  int size = Rank(t);
  int l, r, mid;
  Split(root, size, l, r);
  Split(r, 1, mid, r);
  root = Merge(Merge(mid, l), r);
}

void Bottom(int t) {
  int size = Rank(t);
  int l, r, mid;
  Split(root, size, l, r);
  Split(r, 1, mid, r);
  root = Merge(l, Merge(r, mid));
}

void Insert(int s, int t) {
  if (!t) return;
  int l, lm, rm, r;
  int size = Rank(s);
  if (t==-1) {
    Split(root, size-1, l, r);
    Split(r, 2, lm, r);
    Split(lm, 1, lm, rm);
    root = Merge(l, Merge(Merge(rm, lm), r));
    return;
  }
  Split(root, size, l, r);
  Split(r, 2, lm, r);
  Split(lm, 1, lm, rm);
  root = Merge(l, Merge(Merge(rm, lm), r));
}

int Sa(int s) {
  int l, mid, r;
  Split(root, s-1, l, r);
  Split(r, 1, mid, r);
  root = Merge(l, Merge(mid, r));
  return mid;
}

int main() {
  srand(time(0));
  char opt[7];
  int s, t;
//   freopen("P2596.in", "r", stdin);
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", list+i);
  root = Gen(1, n, 0);
  while (m--) {
    scanf("%s%d", opt, &s);
    switch(opt[0]) {
    case 'T':
      Top(s);
      //cout << "nmsl" << endl;
      break;
    case 'B':
      Bottom(s);
      break;
    case 'I':
      scanf("%d", &t);
      Insert(s, t);
      break;
    case 'A':
      printf("%d\n", Rank(s));
      break;
    case 'Q':
      printf("%d\n", Sa(s));
      break;
    }
  }
  /*
  for (int i = 1; i <= n; i++) {
    cout << i << ',' << Rank(i) << endl;
  }
  */
//   fclose(stdin);
  return 0;
}

甚至下载了样例还在洛谷IDE跑过了

2021/3/22 17:57
加载中...