社区讨论
真正的萌新求助,不知道为什么MLEorz
P3369【模板】普通平衡树参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mi7wj7hw
- 此快照首次捕获于
- 2025/11/21 04:46 4 个月前
- 此快照最后确认于
- 2025/11/21 04:46 4 个月前
rt,我是一个真正的萌新,写的是真正的半看书半写的裸treap,在本地运行会遭遇3221225725。求助QAQ
CPP#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct node{
int lc,rc,valu,pri,cnt,sze;
#define lc(x)t[x].lc
#define rc(x)t[x].rc
#define v(x)t[x].valu
#define p(x)t[x].pri
#define c(x)t[x].cnt
#define s(x)t[x].sze
}t[100100];
int n,tot,root;
void upt(int k)
{
s(k)=s(lc(k))+s(rc(k))+c(k);
}
void zig(int &k)
{
int y=rc(k);
int x=lc(y);
rc(k)=x;
lc(y)=k;
s(y)=s(k);
upt(k);
k=y;
}
void zag(int &k)
{
int y=lc(k);
int x=rc(y);
lc(k)=x;
rc(y)=k;
s(y)=s(k);
upt(k);
k=y;
}
void Insert(int &k,int key){
if (!k){
k=++tot;
v(k)=key;
p(k)=rand();
c(k)=s(k)=1;
lc(k)=rc(k)=0;
return;
}
++s(k);
if (v(k)==key) ++c(k);
else{
if (key<v(k)){
Insert(lc(k),key);
if (p(lc(k))<p(k)) zag(k);
}
else{
Insert(rc(k),key);
if (p(rc(k))<p(k)) zig(k);
}
}
return;
}
void Delete(int &k,int key){
if (v(k)==key){
if (c(k)>1) --c(k),--s(k);
else if (!lc(k)||!rc(k)) k=lc(k)+rc(k);
else if (p(lc(k))<p(rc(k))) zag(k),Delete(k,key);
else zig(k),Delete(k,key);
}
--s(k);
if (key<v(k)) Delete(lc(k),key);
else Delete(rc(k),key);
return;
}
int Queryrank(int k,int num)
{
if (k==0) return 0;
if (v(k)==num) return s(lc(k))+1;
else if (v(k)<num) return s(lc(k))+c(k)+Queryrank(rc(k),num);
else return Queryrank(lc(k),num);
}
int Querynum(int k,int num)
{
if (k==0) return 0;
while (1){
if (num<=s(lc(k))) k=lc(k);
else if (num>s(lc(k))+c(k)) num-=s(lc(k))+c(k),k=rc(k);
else return v(k);
}
}
int Pre(int k,int num)
{
if (k==0) return -2100000000;
if (v(k)>=num) return Pre(lc(k),num);
return max(v(k),Pre(rc(k),num));
}
int Aft(int k,int num)
{
if (k==0) return 2100000000;
if (v(k)<=num) return Aft(rc(k),num);
return min(Aft(lc(k),num),v(k));
}
int main()
{
freopen("testdata3369_2.in","r",stdin);
freopen("testdata3369_2.out","w",stdout);
scanf("%d",&n);
root=tot=0;
for (int I=1;I<=n;I++){
int opt,num;
scanf("%d%d",&opt,&num);
if (opt==1) Insert(root,num);
else if (opt==2) Delete(root,num);
else if (opt==3) printf("%d\n",Queryrank(root,num));
else if (opt==4) printf("%d\n",Querynum(root,num));
else if (opt==5) printf("%d\n",Pre(root,num));
else printf("%d\n",Aft(root,num));
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...