关闭页面特效

平衡树板子

1|0fhq Treap


#include <bits/stdc++.h> using namespace std; #define rg register #define I inline #define gc getchar #define rep(i, a, b) for(int i = a; i <= b; ++i) #define per(i, a, b) for(int i = a; i >= b; --i) I int read(){ rg char ch = gc(); rg int x = 0, f = 0; while(!isdigit(ch)) f |= (ch == '-'), ch = gc(); while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc(); return f ? -x : x; } const int N = 1e5 + 5; int n; int son[N][2], v[N], tot, poe[N], sz[N], root, x, y, z; #define ls son[p][0] #define rs son[p][1] I void up(const int &p){ sz[p] = sz[ls] + sz[rs] + 1; } I int new_node(int a){ sz[++tot] = 1; poe[tot] = rand(); v[tot] = a; return tot; } void split(int p, const int k, int &x, int &y){ if(!p){ x = y = 0; return; } if(v[p] <= k){ x = p; split(rs, k, rs, y); }else{ y = p; split(ls, k, x, ls); } up(p); } int merge(int A, int B){ if(!A || !B) return A | B; if(poe[A] > poe[B]){ son[A][1] = merge(son[A][1], B); up(A); return A; } son[B][0] = merge(A, son[B][0]); up(B); return B; } I void insert(int a){ split(root, a, x, y); root = merge(x, merge(new_node(a), y)); } I void del(int a){ split(root, a, x, z); split(x, a - 1, x, y); y = merge(son[y][0], son[y][1]); root = merge(merge(x, y), z); } I int kth(int p, int k){ if(sz[p] < k) return 0; while(true){ if(sz[ls] >= k) p = ls; else if(sz[ls] + 1 == k) return p; else k -= sz[ls] + 1, p = rs; } } I int pre(int a){ split(root, a - 1, x, y); int p = x; while(rs) p = rs; root = merge(x, y); return p; } I int nxt(int a){ split(root, a, x, y); int p = y; while(ls) p = ls; root = merge(x, y); return p; } int main(){ srand(time(0)); n = read(); int op, a; while(n--){ op = read(); a = read(); switch(op){ case 1: insert(a); break; case 2: del(a); break; case 3: split(root, a - 1, x, y); printf("%d\n", sz[x] + 1); root = merge(x, y); break; case 4: printf("%d\n", v[kth(root, a)]); break; case 5: printf("%d\n", v[pre(a)]); break; case 6: printf("%d\n", v[nxt(a)]); break; } } return 0; }

2|0Splay


#include <iostream> #include <algorithm> #include <cstdio> using namespace std; const int N = 1e5 + 5; #define rg register #define gc getchar #define I inline I int read(){ rg char ch = gc(); rg int x = 0, f = 0; while(!isdigit(ch)) f |= (ch == '-'), ch = gc(); while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc(); return f ? -x : x; } int f[N], sz[N], son[N][2], v[N], cnt[N], tot, root; #define fs(p) (son[f[p]][1] == p) #define ls son[p][0] #define rs son[p][1] void up(int &p){ sz[p] = sz[ls] + sz[rs] + cnt[p]; } I void rot(int &p){ int fa = f[p], ffa = f[fa]; int c = fs(p), cc = fs(fa); son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa; son[p][c ^ 1] = fa; f[fa] = p; if(ffa) son[ffa][cc] = p;// f[p] = ffa; up(fa); up(p); } I void splay(int p, int goal = 0){ if(!p) return; static int fa, ffa; while(f[p] ^ goal){ fa = f[p], ffa = f[fa]; if(ffa ^ goal) rot(fs(p) == fs(fa) ? fa : p); rot(p); } if(!goal) root = p; } I void find(int x){ int p = root; while(v[p] ^ x && son[p][x > v[p]]) p = son[p][x > v[p]]; splay(p); } I void insert(int x){ int p = root; while(v[p] ^ x && son[p][x > v[p]]) p = son[p][x > v[p]]; if(v[p] == x){ ++cnt[p]; } else{ ++tot; if(p) son[p][x > v[p]] = tot; f[tot] = p; sz[tot] = cnt[tot] = 1; v[tot] = x; p = tot; } splay(p); } I int pre(int x){ find(x); if(v[root] < x) return root; int p = son[root][0]; while(rs) p = rs; return p; } int nxt(int x){ find(x); if(v[root] > x) return root; int p = son[root][1]; while(ls) p = ls; return p; } I void del(int x){ find(x); if(v[root] ^ x) return; if(cnt[root] > 1){ --sz[root]; --cnt[root]; return; } if(!son[root][0] || !son[root][1]){ root = son[root][0] | son[root][1]; f[root] = 0; return; } int last = pre(x), nnxt = nxt(x); splay(last); splay(nnxt, last); son[nnxt][0] = 0; } I int kth(int k){ int p = root; if(sz[p] < k) return 0; while(1){ if(sz[ls] >= k) p = ls; else if(sz[ls] + cnt[p] >= k) return p; else k -= sz[ls] + cnt[p], p = rs; } } int n; int main(){ ios::sync_with_stdio(0); n = read(); int op, x; while(n--){ op = read(), x = read(); if(op == 1) insert(x); if(op == 2) del(x); if(op == 3) find(x), cout << sz[son[root][0]] + 1 << '\n'; if(op == 4) cout << v[kth(x)] << '\n'; if(op == 5) cout << v[pre(x)] << '\n'; if(op == 6) cout << v[nxt(x)] << '\n'; } return 0; }

3|0替罪羊树


#include<bits/stdc++.h> using namespace std; #define rg register inline int read(){ rg char ch=getchar(); rg int x=0,f=0; while(!isdigit(ch)) f|=(ch=='-'),ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x; } #define alpha 0.7 struct node{ int del,cnt,sz,val; node *ls,*rs; inline bool isbad(){ return cnt*alpha+5<(ls?ls->cnt:0)||cnt*alpha+5<(rs?rs->cnt:0); } inline void up(){ cnt=sz=0; if(ls) cnt+=ls->cnt,sz+=ls->sz; if(rs) cnt+=rs->cnt,sz+=rs->sz; sz+=!del; ++cnt; } node(int del,int cnt,int sz,int val,node *ls,node *rs):del(del),cnt(cnt),sz(sz),val(val),ls(ls),rs(rs){} }*root,**badtag; inline void dfs(node *p,vector<node*> &v){ if(!p) return; dfs(p->ls,v); if(!p->del) v.push_back(p); dfs(p->rs,v); if(p->del) delete p; } inline node* build(int l,int r,vector<node*> &v){ if(l>r) return NULL; int mid=(l+r)>>1; node *p=v[mid]; p->ls=build(l,mid-1,v); p->rs=build(mid+1,r,v); p->up(); return p; } inline void rebuild(node *&p){ vector<node*> v; dfs(p,v); p=build(0,v.size()-1,v); } inline void insert(int &x,node *&p){ if(!p){ p=new node(0,1,1,x,NULL,NULL); return; } ++p->cnt,++p->sz; if(x<=p->val) insert(x,p->ls); else insert(x,p->rs); if(p->isbad()) badtag=&p; else if(badtag){ p->cnt-=(*badtag)->cnt-(*badtag)->sz; } } inline void insert(int x){ badtag=NULL; insert(x,root); if(badtag) rebuild(*badtag); } inline int mink(int k){ node *p=root; int ans=1; while(p){ if(p->val<k) ans+=(!p->del+(p->ls?p->ls->sz:0)),p=p->rs; else p=p->ls; } return ans; } inline int kth(int k){ node *p=root; while(p){ if(!p->del&&(p->ls?p->ls->sz:0)+1==k) return p->val; if((p->ls?p->ls->sz:0)>=k) p=p->ls; else k-=(p->ls?p->ls->sz:0)+!p->del,p=p->rs; } } inline void erase(int k,node *p){ while(p){ --p->sz; if(!p->del&&(p->ls?p->ls->sz:0)+1==k){ p->del=1; return; } if((p->ls?p->ls->sz:0)>=k) p=p->ls; else k-=(p->ls?p->ls->sz:0)+!p->del,p=p->rs; } } int n; int main(){ n=read(); int op,x; while(n--){ op=read(),x=read(); if(op==1) insert(x); else if(op==2) erase(mink(x),root); else if(op==3) printf("%d\n",mink(x)); else if(op==4) printf("%d\n",kth(x)); else if(op==5) printf("%d\n",kth(mink(x)-1)); else if(op==6) printf("%d\n",kth(mink(x+1))); } return 0; }

__EOF__

作  者__int 256
出  处https://www.cnblogs.com/int256/p/16512269.html
关于博主:编程路上的小学生,热爱技术,喜欢专研。评论和私信会在第一时间回复。或者直接私信我。
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!

posted @   __int256  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
0
0
关注
跳至底部
点击右上角即可分享
微信分享提示