支持:
插入
删除
查找
最大值
最小值
尺寸记录
(支持重复元素)
#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;
}