Treap模板(中级版)
来源:互联网 发布:穿帮镜头软件 编辑:程序博客网 时间:2024/05/20 20:20
支持:
插入
删除
查找
最大值
最小值
尺寸记录
(支持重复元素)
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include<queue>#include<vector>#include<climits>#include<string>#include<cstdlib>#include<set>#include<stack>#include<map>#include<bitset>#include<ctime>using namespace std;typedef int ll;typedef unsigned long long ull;inline ll read(){ char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar()); ll x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=x*10+ls-'0'; if(k=='-')x=0-x;return x;}struct E{ ll lc,rc;//左右孩子 ll s,sum;//权值和随机数 ll fa;//父亲 ll size;//子节点大小 ll js;//该节点元素计数 }t[1000050];ll w;ll size;ll root;inline ll find(ll s)//查找 { if(size==0) return 0; ll now=root; while(now) { if(t[now].s==s) return now; if(s<t[now].s) { now=t[now].lc; continue; } if(s>t[now].s) { now=t[now].rc; continue; } } return 0;}ll maxn()//最大值 { ll now=root; while(1) { if(t[now].rc==0) return now; now=t[now].rc; }}ll minn()//最小值 { ll now=root; while(1) { if(t[now].lc==0) return now; now=t[now].lc; }}void update(ll x)//更新平衡树尺寸{ ll now=root; while(1) { --t[now].size; if(now==x)return; if(t[x].s<t[now].s) { now=t[now].lc; continue; } if(t[x].s>t[now].s) { now=t[now].rc; continue; } } return;}void zig(ll x)//左旋 { t[t[x].fa].size-=t[t[x].rc].size; t[t[x].fa].size-=t[x].js; t[x].size+=t[t[t[x].fa].lc].size; t[x].size+=t[t[x].fa].js; if(root==t[x].fa) root=x; ll ff=t[t[x].fa].fa; t[t[x].fa].fa=x; if(ff!=0) { if(t[ff].lc==t[x].fa) t[ff].lc=x; if(t[ff].rc==t[x].fa) t[ff].rc=x; } if(t[x].lc!=0) t[t[x].lc].fa=t[x].fa; t[t[x].fa].rc=t[x].lc; t[x].lc=t[x].fa; t[x].fa=ff; return;}void zag(ll x)//右旋 { t[t[x].fa].size-=t[t[x].lc].size; t[t[x].fa].size-=t[x].js; t[x].size+=t[t[t[x].fa].rc].size; t[x].size+=t[t[x].fa].js; if(root==t[x].fa) root=x; ll ff=t[t[x].fa].fa; t[t[x].fa].fa=x; if(ff!=0) { if(t[ff].lc==t[x].fa) t[ff].lc=x; if(t[ff].rc==t[x].fa) t[ff].rc=x; } if(t[x].rc!=0) t[t[x].rc].fa=t[x].fa; t[t[x].fa].lc=t[x].rc; t[x].rc=t[x].fa; t[x].fa=ff; return;}void strike_off(ll x)//删除指定下标 { while(t[x].lc!=0||t[x].rc!=0) { if(t[x].lc!=0&&t[x].rc==0) {zag(t[x].lc);continue;} if(t[x].rc!=0&&t[x].lc==0) {zig(t[x].rc);continue;} if(t[x].lc!=0&&t[x].rc!=0) { if(t[t[x].lc].sum<t[t[x].rc].sum) zag(t[x].lc); else zig(t[x].rc); } } update(x); if(t[x].fa!=0) { if(t[t[x].fa].lc==x) t[t[x].fa].lc=0; if(t[t[x].fa].rc==x) t[t[x].fa].rc=0; } --size; if(size==0) root=0; return;}void delete_(ll s)//删除指定数字{ ll x=find(s); if(x==0) return; if(t[x].js>1) { --t[x].js; --size; update(x); return; } else strike_off(x); return;}void insert(ll s)//插入 { ++size; t[++w].s=s; t[w].sum=rand()%1000050; t[w].size=1; t[w].js=1; if(size==1) { root=w; return; } ll pre=root; ll now=root; while(now!=0) { if(s==t[now].s) { ++t[now].size; ++t[now].js; --w; return; } if(s<t[now].s) { ++t[now].size; pre=now; now=t[now].lc; continue; } if(s>t[now].s) { ++t[now].size; pre=now; now=t[now].rc; continue; } } if(s<t[pre].s) t[pre].lc=w; if(s>t[pre].s) t[pre].rc=w; t[w].fa=pre; while(t[w].sum<t[t[w].fa].sum) { if(t[t[w].fa].lc==w) { zag(w); continue; } if(t[t[w].fa].rc==w) { zig(w); continue; } } return;}int main(){ srand(19981017); return 0;}
0 0
- Treap模板(中级版)
- Treap模板(简单版)
- [ 模板 ] Treap指针版
- 【模板】treap(数组)
- Treap模板(豪华版)
- TREAP 模板(新)
- Treap模板(旋转)
- 【Treap】Treap模板
- Treap模板+Treap介绍。。。
- Treap模板
- 【Treap模板】
- (模板)treap
- treap 模板
- Treap模板
- treap 模板
- treap模板
- Treap 模板
- 【模板】Treap
- 过多if-else分支的优化
- 要学习的东西6.11
- iOS给工程中选中的文件创建分组文件夹(小技巧)
- 剑指offer(16)-顺时针打印矩阵
- IPC机制
- Treap模板(中级版)
- 121~123188 Best Time to Buy and Sell StockI II III IV
- (心态篇)空杯心态,一个程序员的自我修炼
- 关于if else优化
- (第20讲)各种排序总结
- 浅谈设计模式总结
- 1. Two Sum
- 链表面试题总结(一)
- 不得姐实战教程 01 基本配置