平衡树

update 窝 再 也 不 要 写 splay 或 leafytree 了

文艺平衡树

#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));
}
原文地址:https://www.cnblogs.com/ZUTTER/p/10176822.html