社区讨论
手写的和复制的板子,为什么都错了
P6136【模板】普通平衡树(数据加强版)参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lo7xyqdv
- 此快照首次捕获于
- 2023/10/27 09:35 2 年前
- 此快照最后确认于
- 2023/10/27 09:35 2 年前
RT,复制了我别的题的 Treap 板子,然后错了。
接着我自己重新写了一遍Treap, 怒拿 48分,这是什么原因?
CPP#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;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...