社区讨论
本人萌新,初学OI,替罪羊数写炸了QAQ
P3369【模板】普通平衡树参与者 11已保存回复 16
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 16 条
- 当前快照
- 1 份
- 快照标识符
- @mi6xurxa
- 此快照首次捕获于
- 2025/11/20 12:35 4 个月前
- 此快照最后确认于
- 2025/11/20 15:23 4 个月前
CPP
#include<bits/stdc++.h>
const int MAXN=100010;
const int INF=0x7f7f7f7f;
const double alpha=0.75;
typedef double D;
using namespace std;
int n,m,i,j,k,opt,x;
struct sgt{
int lson,rson,size,val,tot,exist=1;
};
sgt tree[MAXN];
int g[MAXN],temp[MAXN],g_t,root,t_t;
struct io{
int read(){
int x=0;char c;
for(c=getchar();!isdigit(c);c=getchar()) ;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return x;
}
void write(int x){
if(x/10>0) write(x/10);
putchar(x%10+48);
return;
}
}Fio;
#define read Fio.read
#define write Fio.write
namespace SGT{
bool bad(int x){
if((D)(max(tree[tree[x].lson].size,tree[tree[x].rson].size))>=tree[x].size*alpha) return 1;
else return 0;
}
void dfs(int x){
if(x==0) return;
dfs(tree[x].lson);
if(tree[x].exist==1) temp[++t_t]=x;
else g[++g_t]=x;
dfs(tree[x].rson);
}
void bulid(int l,int r,int&now){
int mid=(l+r)/2;
now=temp[mid];
if(l==r){
tree[now].lson=0;tree[now].rson;
tree[now].size=1;tree[now].tot=1;tree[now].exist=1;
return;
}
if(l<mid) bulid(l,mid-1,tree[now].lson);
else tree[now].lson=0;
bulid(mid+1,r,tree[now].rson);
tree[now].size=tree[tree[now].lson].size+tree[tree[now].rson].size+1;
tree[now].tot=tree[tree[now].lson].tot+tree[tree[now].rson].tot+1;
return;
}
void rebuild(int&now){
t_t=0;
dfs(now);
if(t_t==0) bulid(1,t_t,now);
else now=0;
}
void insert(int &now,int val){
if(now==0){
now=g[g_t--];
tree[now].val=val;
tree[now].lson=0;tree[now].rson=0;
tree[now].size=1;tree[now].exist=1;tree[now].tot=1;
return;
}
tree[now].size++;tree[now].tot++;
if(tree[now].val>=val) insert(tree[now].lson,val);
else insert(tree[now].rson,val);
if(bad(now)==1) rebuild(now);
}
int Qrank(int k){
int now=root;
int ans=1;
while(now>0){
if(tree[now].val>=k) now=tree[now].lson;
else{
ans+=tree[tree[now].lson].size+tree[tree[now].rson].exist;
now=tree[now].rson;
}
}
return ans;
}
int Frank(int k){
int now=root;
while(now>0){
if(tree[now].exist==1&&tree[tree[now].lson].size+1==k) return tree[now].val;
else if(tree[tree[now].lson].size+1>k) now=tree[now].lson;
else{
k-=(tree[tree[now].lson].size+tree[now].exist);
now=tree[now].rson;
}
}
return INF;
}
void delRank(int &now,int k){
if(tree[now].exist==1&&tree[tree[now].lson].size+1==k){
tree[now].exist=0;tree[now].size--;
return;
}
tree[now].size--;
if(tree[tree[now].lson].size+1>=k){
now=tree[now].lson;
delRank(now,k);
}
else{
now=tree[now].rson;
k-=(tree[tree[now].lson].size+tree[now].exist);
delRank(now,k);
}
return;
}
void delNode(int k){
delRank(root,Frank(k));
if(tree[root].tot*alpha>=tree[root].size) rebuild(root);
}
}
int main(){
n=read();
for(int _i=MAXN-1;_i>=1;_i--) g[++g_t]=_i;
for(int _i=1;_i<=n;_i++){
scanf("%d %d",&opt,&x);
if(opt==1) SGT::insert(root,x);
else if(opt==2) SGT::delNode(x);
else if(opt==3) printf("%d\n",SGT::Qrank(x));
else if(opt==4) printf("%d\n",SGT::Frank(x));
else if(opt==5) printf("%d\n",SGT::Frank(SGT::Qrank(x)-1));
else printf("%d\n",SGT::Frank(SGT::Qrank(x+1)));
}
}
回复
共 16 条回复,欢迎继续交流。
正在加载回复...