手写的和复制的板子,为什么都错了

P6136 【模板】普通平衡树(数据加强版)

青鸟_Blue_Bird @ 2022-09-28 23:06:13

RT,复制了我别的题的 Treap 板子,然后错了。 接着我自己重新写了一遍Treap, 怒拿 48分,这是什么原因?

#pragma comment(linker, "/STACK:102400000,102400000")//手动开大栈区

#include <bits/stdc++.h>
using namespace std;
#define N 2000010
#define int long long
#define ll long long
const ll INF = 2e15; 

template <class T>
inline void read(T& a){
    T x = 0, s = 1;
    char c = getchar();
    while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
    while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
    a = x * s;
    return ;
}

struct node{
  int val, pri, siz, cnt, ch[2]; 
} t[N];  

int root = 0; 
int tot = 0;

#define lson ch[0]
#define rson ch[1]

int build(int x){
  t[++tot].val = x;
  t[tot].pri = (ll)rand() * rand() % (ll)1e15 + 1; 
  t[tot].siz = 1; 
  t[tot].cnt = 1; 
  return tot; 
}

inline void pushup(int now){
  t[now].siz = t[t[now].lson].siz + t[t[now].rson].siz + t[now].cnt; 
  return ; 
}

void rotate(int& now, int d){
  int x = t[now].ch[d^1]; 
  t[now].ch[d^1] = t[x].ch[d]; 
  t[x].ch[d] = now; 
  now = x; 
  pushup(t[now].ch[d]); pushup(now); 
  return ; 
}

void insert(int& now, int x){
  if(!now){
    now = build(x); 
    return ; 
  }
  if(t[now].val == x){
    t[now].cnt++; 
  }
  else{
    int d = x < t[now].val ? 0 : 1; 
    insert(t[now].ch[d], x); 
    if(t[now].pri < t[t[now].ch[d]].pri) rotate(now, d ^ 1); 
  }
  pushup(now); 
  return ; 
}

void del(int& now, int x){
  if(!now) return ; 
  if(t[now].val == x) {
    if(t[now].cnt >= 2) t[now].cnt--, pushup(now); 
    else{
      if(t[now].lson || t[now].rson){
        if(!t[now].rson || t[t[now].lson].pri > t[t[now].rson].pri){
          rotate(now, 1);
          del(t[now].rson, x); 
        }
        else rotate(now, 0), del(t[now].lson, x); 
      }
      else now = 0;   // 直接删除
    }
  }
  else{
    if(x < t[now].val) del(t[now].lson, x); 
    else del(t[now].rson, x); 
    pushup(now); 
  }
  pushup(now); 
  return ; 
}

int get_rank(int& now, int x){
  if(!now) return 1; 
  if(t[now].val == x){
    return t[t[now].lson].siz + 1; 
  }
  if(t[now].val < x){
    return t[t[now].lson].siz + t[now].cnt + get_rank(t[now].rson, x); 
  }
  if(t[now].val > x){
    return get_rank(t[now].lson, x); 
  }
  return 0; 
}

int find_kth(int& now, int k){
  if(!now) return 0; 
  if(t[t[now].lson].siz >= k) return find_kth(t[now].lson, k);
  else if(t[t[now].lson].siz + t[now].cnt >= k) return t[now].val; 
  else return find_kth(t[now].lson, k - t[t[now].lson].siz - t[now].cnt); 
}

int get_pre(int now, int x){
  if(!now) return -INF; 
  if(t[now].val >= x) return get_pre(t[now].lson, x); 
  else return max(t[now].val, get_pre(t[now].rson, x)); 
}

int get_next(int now, int x){
  if(!now) return INF; 
  if(t[now].val <= x) return get_next(t[now].rson, x); 
  else return min(t[now].val, get_next(t[now].lson, x)); 
}

inline void init(){
  root = build(-INF); t[root].rson = build(INF);
  pushup(root);
  return ; 
}

signed main(){
  // freopen("hh.txt", "r", stdin); 
  // freopen("out.txt", "w", stdout); 
  srand(time(0)); 
  int n, Q;
  read(n), read(Q);
  // init(); 
  for(int i = 1; i <= n; i++){
    int x; read(x); 
    insert(root, x); 
  }
  int ans = 0, last = 0; 
  while(Q--){
    int opt, x; 
    read(opt), read(x);
    x ^= last; 
    if(opt == 1) insert(root, x);
    else if(opt == 2) del(root, x); 
    else if(opt == 3){
      insert(root, x); 
      last = get_rank(root, x); 
      del(root, x); 
      ans ^= last; 
    }
    else if(opt == 4){
      last = find_kth(root, x); 
      ans ^= last; 
    }
    else if(opt == 5){
      last = get_pre(root, x); 
      ans ^= last; 
    }
    else if(opt == 6){
      last = get_next(root, x);
      ans ^= last;  
    }
    // printf("Q: %lld last: %lld\n", Q, last); 
    // cout << "ans     " << ans << endl; 
  }
  cout << ans << endl;
  return 0;
}

by 青鸟_Blue_Bird @ 2022-09-28 23:30:06

此题已经AC, 此贴终结。错误原因:找 kth 的时候,右儿子打成左儿子了。。。。。

立在此处警示后人!


by wocaicai @ 2022-09-29 00:21:49

/jk


by register_new @ 2022-09-29 07:37:41

@青鸟_Blue_Bird 赶紧删帖,小心有人抄袭代码


|