一些东西
template<typename T>
class Balanced_Tree{
private:
struct node{
int ls,rs,num,siz;
T val;
int cnt;
};
node *tr;
int *id;
int cnt,tot;
const double B=0.80;
T Min,Max;
void GetID(int p){
if(tr[p].ls) GetID(tr[p].ls);
if(tr[p].num>tr[tr[p].ls].num+tr[tr[p].rs].num) id[++cnt]=p;
if(tr[p].rs) GetID(tr[p].rs);
tr[p].ls=tr[p].rs=0;
}
int ReBuild(int l,int r){
if(r<l) return 0;
int mid=l+r>>1;
int rt=id[mid];
tr[rt].ls=ReBuild(l,mid-1);
tr[rt].rs=ReBuild(mid+1,r);
tr[rt].num=tr[rt].cnt+tr[tr[rt].ls].num+tr[tr[rt].rs].num;
tr[rt].siz=tr[tr[rt].ls].siz+tr[tr[rt].rs].siz+1;
return rt;
}
void insert(int& p,T x){
if(!p){
p=++tot;
tr[p]={0,0,1,1,x,1};
return;
}
if(tr[p].val==x){
tr[p].num++;
tr[p].cnt++;
return;
}
if(tr[p].val>x) insert(tr[p].ls,x);
if(tr[p].val<x) insert(tr[p].rs,x);
tr[p].num++;
tr[p].siz=tr[tr[p].ls].siz+tr[tr[p].rs].siz+1;
if(1.0*max(tr[tr[p].ls].siz,tr[tr[p].rs].siz)>1.0*B*tr[p].siz){
cnt=0;
GetID(p);
p=ReBuild(1,cnt);
}
}
void del(int p,T x){
if(tr[p].val==x){
if(tr[p].cnt) tr[p].num--,tr[p].cnt--;
return;
}
if(tr[p].val>x&&tr[p].ls) del(tr[p].ls,x);
if(tr[p].val<x&&tr[p].rs) del(tr[p].rs,x);
tr[p].num=tr[p].cnt+tr[tr[p].ls].num+tr[tr[p].rs].num;
tr[p].siz=tr[tr[p].ls].siz+tr[tr[p].rs].siz+1;
}
T gn(int p,int rk){
if(rk-tr[tr[p].ls].num>0&&rk<=tr[p].num-tr[tr[p].rs].num) return tr[p].val;
if(rk<=tr[tr[p].ls].num) return gn(tr[p].ls,rk);
else return gn(tr[p].rs,rk-tr[p].num+tr[tr[p].rs].num);
}
public:
int Root;
void Build(int N){
cnt=tot=0;
tr=new node[N];
id=new int[N];
}
bool Empty(){
return !tr[Root].num;
}
void Set(T minn,T maxx){
Min=minn,Max=maxx;
}
void Clear(){
cnt=tot=0;
}
void Insert(T x){
insert(Root,x);
}
void Delete(int x){
del(Root,x);
}
int GetCount(T x){
int p=Root;
while(p&&tr[p].val!=x){
if(tr[p].val>x) p=tr[p].ls;
else p=tr[p].rs;
}
if(p) return tr[p].cnt;
return 0;
}
int GetRank(T x){
int ans=0,p=Root;
while(p&&tr[p].val!=x){
if(tr[p].val<x) ans+=tr[p].cnt+tr[tr[p].ls].num,p=tr[p].rs;
else p=tr[p].ls;
}
return ans+tr[tr[p].ls].num+1;
}
T GetVal(int rk){
if(rk<1) return Min;
if(rk>tr[Root].num) return Max;
return gn(Root,rk);
}
T GetPrev(T x){
assert(!Empty());
return GetVal(GetRank(x)-1);
}
T GetNext(T x){
assert(!Empty());
return GetVal(GetRank(x)+GetCount(x));
}
};
定义方式:
Balanced_Tree<Type> Name;
需要定义大于号、小于号。
支持操作:
Name.Build(int N)建树(其实就是申请空间)\(O(1)\)Name.Insert(T x)插入一个元素 \(O(\log n)\)Name.Delete(T x)删除一个元素(如有多个只删除一个,没有就不删)\(O(\log n)\)Name.GetRank(T x)求排名(准确来说是小于这个值的元素的个数加一) \(O(\log n)\)Name.GetVal(int rk)根据排名求值 \(O(\log n)\)Name.GetPrev(T x)前驱 \(O(\log n)\)Name.GetNext(T x)后继 \(O(\log n)\)Name.GetCount(T x)求某一个值出现的次数 \(O(\log n)\)Name.Clear()清空 \(O(1)\)Name.Set(T minn,T maxx)设置极大值、极小值(用于求前驱后继)\(O(1)\)
据 fqr 说,在这道题中总时间跑进 \(10\text{s}\) 就算比较快了,用这个平衡树再加上 fread 可以获得总时间 \(8\text{s}\) 的好成绩。
i AM a LAD,ANd Fine.

浙公网安备 33010602011771号