码迷,mamicode.com
首页 > 其他好文 > 详细

平衡树

时间:2018-12-25 22:53:01      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:space   putc   class   upd   har   git   name   amp   cst   

文艺平衡树

#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));
}

平衡树

标签:space   putc   class   upd   har   git   name   amp   cst   

原文地址:https://www.cnblogs.com/ZUTTER/p/10176822.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!