您的位置:首页 > 其它

BZOJ3224: Tyvj 1728 普通平衡树

2014-11-04 12:41 260 查看
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3224

题解:

复习了一下treap,也算是一个完整的模板了吧。

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<iostream>
#include<queue>
#define for0(i,n) for(int i=0;i<=n;i++)
#define for1(i,n) for(int i=1;i<=n;i++)
#define for2(i,x,y) for(int i=x;i<=y;i++)
#define for3(i,y,x) for(int i=y;i>=x;i--)
#define maxn (3000000+5)
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
int tot,rt,s[maxn],l[maxn],r[maxn],v[maxn],w[maxn],h[maxn];
inline void pushup(int k)
{
s[k]=s[l[k]]+s[r[k]]+w[k];
}
inline void lturn(int &k)
{
int t=r[k];r[k]=l[t];l[t]=k;s[t]=s[k];pushup(k);k=t;
}
inline void rturn(int &k)
{
int t=l[k];l[k]=r[t];r[t]=k;s[t]=s[k];pushup(k);k=t;
}
inline void ins(int &k,int x)
{
if(!k){k=++tot;s[k]=w[k]=1;v[k]=x;h[k]=rand();return;}
s[k]++;
if(x==v[k])w[k]++;
else if(x<v[k]){ins(l[k],x);if(h[l[k]]>h[k])rturn(k);}
else {ins(r[k],x);if(h[r[k]]>h[k])lturn(k);}
}
inline void del(int &k,int x)
{
if(v[k]==x)
{
if(w[k]>1)w[k]--,s[k]--;
else if(l[k]*r[k]==0)k=l[k]+r[k];
else if(h[l[k]]>h[r[k]]){rturn(k);del(k,x);}
else {lturn(k);del(k,x);}
return;
}
s[k]--;
if(x<v[k])del(l[k],x);else del(r[k],x);
}
inline int find(int k,int x)
{
if(s[l[k]]<x&&s[l[k]]+w[k]>=x)return v[k];
else if(s[l[k]]>=x)return find(l[k],x);
else return find(r[k],x-s[l[k]]-w[k]);
}
inline int rank(int k,int x)
{
if(!k)return 0;
if(v[k]==x)return s[l[k]];
else if(x<v[k])return rank(l[k],x);
else return s[l[k]]+w[k]+rank(r[k],x);
}
inline int prev(int k,int x)
{
if(!k)return x;
if(x<=v[k])return prev(l[k],x);
else {int t=prev(r[k],x);return t==x?v[k]:t;}
}
inline int next(int k,int x)
{
if(!k)return x;
if(v[k]<=x)return next(r[k],x);
else {int t=next(l[k],x);return t==x?v[k]:t;}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int m=read();
while(m--)
{
int ch=read(),x=read();
if(ch==1)ins(rt,x);
else if(ch==2)del(rt,x);
else if(ch==3)printf("%d\n",rank(rt,x)+1);
else if(ch==4)printf("%d\n",find(rt,x));
else if(ch==5)printf("%d\n",prev(rt,x));
else printf("%d\n",next(rt,x));
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: