平衡树
Posted zutter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了平衡树相关的知识,希望对你有一定的参考价值。
文艺平衡树
#include<iostream>
#include<cstdio>
#define new_Node(t,s,v,a,b) (&(*st[cnt++]=Node(t,s,v,a,b)))
#define update(now) if(now->left->size)now->size=now->left->size+now->right->size,now->value=now->right->value
#define Al 0.19
using namespace std;
int cnt,i,m,n,j,k,top,l,r,s[15];
struct Node
{
int size,value,tag;
Node *left,*right;
Node(int t,int s,int v,Node *a,Node *b):tag(t),size(s),value(v),left(a),right(b){}
Node(){}
} *root,*st[400001],t[400001],*father,*null,*tail,*w,*e,*g,*o,ss;
inline char gc()
{
static char now[1<<22],*S,*T;
if (T==S)
{
T=(S=now)+fread(now,1,1<<22,stdin);
if (T==S) return EOF;
}
return *S++;
}
void put(int x)
{
int k=10,t=0;
while(x)
{
s[++t]=x%10;
x/=10;
}
if(!t) putchar(‘0‘);
for(int i=t;i>=1;i--) putchar(s[i]+‘0‘);
putchar(‘ ‘);
}
inline int read()
{
register int x=0,f=1;
register char ch=gc();
while(!isdigit(ch))
{
if (ch==‘-‘) f=-1;
ch=gc();
}
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-‘0‘,ch=gc();
return x*f;
}
inline void push(Node *now)
{
if((!(now->tag))||(now->size==1)) return ;
swap(now->left,now->right);
now->tag=0;
if(now->left!=null)now->left->tag^=1;
if(now->right!=null) now->right->tag^=1;
}
Node* built(int ll,int rr)
{
if(ll==rr) return new_Node(0,1,ll,null,null);
int mid=(ll+rr)>>1;
Node* lll=built(ll,mid);
Node* rrr=built(mid+1,rr);
Node* p=new_Node(0,rr-ll+1,rr,lll,rrr);
return p;
}
Node* sp(Node* now,int k)
{
if(now->size==k) return now;
if(now->tag)push(now);
if(now->left->size>=k)
{
bool b=0; if(now->left->tag)push(now->left);
if(now->left->size==k) b=1;
Node* e=sp(now->left,k);
if(b)st[--cnt]=now->right, *now=*now->right;
update(now);
return e;
}
if(now->right->tag) push(now->right);
Node* x=sp(now->right,k-now->left->size);
Node* r=new_Node(0,0,0,now->left,x);
st[--cnt]=now->right;
*now=*now->right;
update(now);
update(r);
return r;
}
Node* mrge(Node*& x,Node*& y)
{
if(y->size>=Al/(1-Al)*x->size) return new_Node(0,x->size+y->size,y->value,x,y);
if(x->tag)push(x); if(y->tag)push(y);
if(x->left->size>=Al*(x->size+y->size))
{
Node* l=mrge(x->right,y);
Node* r=new_Node(0,x->size+y->size,y->value,x->left,l);
st[--cnt]=x;
return r;
}
if(x->right->tag)push(x->right);
Node* l=mrge(x->left,x->right->left);
Node* r=mrge(x->right->right,y);
int z=x->size+y->size, u=y->value;
st[--cnt]=x;
return new_Node(0,z,u,l,r);
}
int ask(Node* now,int k)
{
if(now->size==1) return now->value;
if(now->tag) push(now);
if(now->left->size>=k) return ask(now->left,k);
return ask(now->right,k-now->left->size);
}
int main()
{
n=read(); m=read();
for(register int i=0;i<400001;i++) st[i]=&t[i];
null=new_Node(0,0,0,0,0);
root=built(1,n);;
for(m;m;m--)
{
l=read(); r=read();
w=g=null;
if(l-1)w=sp(root,l-1);
if(r-l+1)g=sp(root,r-l+1);
g->tag^=1;
if(w!=null)g=mrge(w,g);
if(g!=null)root=mrge(g,root);
}
for(register int i=1;i<=n;i++) put(ask(root,i));
}
以上是关于平衡树的主要内容,如果未能解决你的问题,请参考以下文章