• 平衡树


    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));
    }
    
  • 相关阅读:
    如何在Elasticsearch中解析未分配的分片(unassigned shards)
    spark-streaming获取kafka数据的两种方式
    hbase读写优化
    手动修复 under-replicated blocks in HDFS
    kubectl常用命令(个人记录)
    mysql远程访问被拒绝问题
    海盗分金问题
    《转》基于OpenCV的傅里叶变换及逆变换
    char*,string和CString之间的转换
    commons-fileupload 核心API 分析
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/10176822.html
Copyright © 2020-2023  润新知