社区讨论
刚学OI的萌新求助替罪羊树
P3369【模板】普通平衡树参与者 5已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @lo37y65l
- 此快照首次捕获于
- 2023/10/24 02:16 2 年前
- 此快照最后确认于
- 2023/11/12 18:50 2 年前
萌新刚学OI,第一次学替罪羊树,只有16分,剩下的又WA又T qwq
求助各路大佬!悬赏一个关注(要是我忘了麻烦私信提醒我())
代码如下
CPP#include <iostream>
#include <cstdio>
#include <math.h>
#include <algorithm>
#include <istream>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <string.h>
#include <map>
#include <unordered_map>
#include <random>
#include <bitset>
//#define int long long
//#define double long double
#define p1(x) x.first
#define p2(x) x.second
#define i128 __int128_t
//#pragma GCC optimize(2)
#define w(x) t[x].w
#define siz(x) t[x].siz
#define fa(x) t[x].fa
#define lc(x) t[x].c[0]
#define rc(x) t[x].c[1]
#define d(x) t[x].d
#define dc(x) t[x].dc
#define pii pair<int,int>
//若汁记好了以后再用Ctrl+C/+V你就是狗
using namespace std;
int n;
const double alpha=0.7,bta=0.5;
struct node {
int siz,w,fa,dc;
int c[2];
bool d;
}t[100300];
int a[100300];
int cnt;
int ct=0;
int rt=0;
inline void upd(int x){
dc(x)=dc(lc(x))+dc(rc(x))+d(x);
siz(x)=siz(lc(x))+siz(rc(x))+1;
}
inline int tsiz(int x){
return siz(x)-dc(x);
}
inline void trs(int x){
if(lc(x))trs(lc(x));
if(!d(x))
a[++ct]=x;
if(rc(x))trs(rc(x));
}
inline int rb(int l,int r){
if(r<l)return 0;
if(l==r){
siz(a[l])=1;
lc(a[l])=rc(a[l])=0;
dc(a[l])=0;
return a[l];
}
else if(l==r-1){
rc(a[l])=a[r];
siz(a[r])=1;
siz(a[l])=2;
lc(a[l])=lc(a[r])=rc(a[r])=0;
fa(a[r])=a[l];
dc(a[l])=dc(a[r])=0;
return a[l];
}
int mid=l+r>>1;
siz(a[mid])=r-l+1;
dc(a[mid])=0;
lc(a[mid])=rb(l,mid-1);
fa(lc(a[mid]))=a[mid];
rc(a[mid])=rb(mid+1,r);
fa(rc(a[mid]))=a[mid];
return a[mid];
}
inline void chk(int x){
if(max(siz(lc(x)),siz(rc(x)))>siz(x)*alpha||dc(x)>siz(x)*bta){
ct=0;
trs(x);
bool p=x==t[fa(x)].c[1];
int f=fa(x);
t[fa(x)].c[p]=rb(1,ct);
fa(t[f].c[p])=f;
}
}
inline int nnd(int x){
++cnt;
w(cnt)=x;
siz(cnt)=1;
return cnt;
}
inline void ins(int &x,int v){
if(!x){
x=nnd(v);
return ;
}
if(v<w(x))
ins(lc(x),v),fa(lc(x))=x;
else ins(rc(x),v),fa(rc(x))=x;
upd(x);
chk(x);
}
inline void del(int &x,int k){
if(!x)return ;
int tmp=tsiz(x)-tsiz(rc(x));
if(tmp==k&&!d(x)){
d(x)=1;
dc(x)++;
return ;
}
if(tmp<=k)
del(lc(x),k);
else del(rc(x),k-tmp);
upd(x);
chk(x);
}
inline int rk(int &x,int v){
if(!x)return 1;
if(w(x)>=v)
return rk(lc(x),v);
else return tsiz(x)-tsiz(rc(x))+rk(rc(x),v);
}
inline int kth(int &x,int k){
int tmp=tsiz(x)-tsiz(rc(x));
if(k>tmp){
k-=tmp;
return kth(rc(x),k);
}
else if(k<tmp)return kth(lc(x),k);
else {
if(!d(x))return w(x);
else return kth(lc(x),k);
}
}
inline int pre(int &x,int v){
return kth(x,rk(x,v)-1);
}
inline int suf(int &x,int v){
return kth(x,rk(x,v+1));
}
signed main(){
ios::sync_with_stdio(0);
// freopen("","r",stdin);
// freopen("","w",stdout);
cin>>n;
while(n--){
int op,x;
cin>>op>>x;
if(op==1)ins(rt,x);
else if(op==2)del(rt,rk(rt,x));
else if(op==3)cout<<rk(rt,x)<<endl;
else if(op==4)cout<<kth(rt,x)<<endl;
else if(op==5)cout<<pre(rt,x)<<endl;
else cout<<suf(rt,x)<<endl;
}
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...