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

leafy tree

时间:2018-12-25 20:07:34      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:lse   swa   ever   ++   har   name   upd   排名   print   

看起来整个题解区都没有一个leafy tree的题解,那我就来贡献一个吧

调了一个晚上的心血啊

#include<cstdio>
#include<iostream>
#define ls tree[node].l
#define rs tree[node].r
#define merge(a,b) new_Node(tree[b].value,tree[a].size+tree[b].size,a,b)
using namespace std;
const int maxN=3e5 + 100,ratio=4;
struct leafy
{
    int value,size;
    int l,r;
}tree[maxN*2+1];
int cnt,root;
int read()
{
    int num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) num=(num<<3)+(num<<1)+(ch^48),ch=getchar();
    return num*f;
}
int new_Node(int value,int size,int l,int r)//创建新节点 
{
    int node=++cnt;
    tree[node]=(leafy){value,size,l,r};
    return node;
}
void update(int node)
{
    if(!tree[node].l) {tree[node].size=1; return;}
    tree[node].size=tree[ls].size+tree[rs].size; tree[node].value=tree[rs].value;
}
void rotate(int node)//旋转 
{
    if(tree[ls].size>tree[rs].size*ratio) rs=merge(tree[ls].r,rs),ls=tree[ls].l;
    if(tree[rs].size>tree[ls].size*ratio) ls=merge(ls,tree[rs].l),rs=tree[rs].r;
}
int rank(int node,int x)//查x的排名 
{
    if(tree[node].size==1) return 1;
    if(x>tree[ls].value) return tree[ls].size+rank(rs,x);
    else return rank(ls,x); 
}
int find(int node,int x)//查排名为x的数 
{
    if(tree[node].size==1) return tree[node].value;
    if(x>tree[ls].size) return find(rs,x-tree[ls].size);
    else return find(ls,x);
}
void insert(int node,int x)//插入x 
{
    if(tree[node].size==1) ls=new_Node(min(tree[node].value,x),1,0,0),rs=new_Node(max(tree[node].value,x),1,0,0);
    else insert(x>tree[ls].value?rs:ls,x);
    update(node); rotate(node);
}
void del(int node,int x)//删除x 
{
    int now,other;
    if(x>tree[ls].value) now=rs,other=ls;
    else now=ls,other=rs;
    if(tree[now].size==1)
        if(x==tree[now].value)
        {
            tree[node].l=tree[other].l;
            tree[node].r=tree[other].r;
            tree[node].value=tree[other].value;
        }else return;
    else del(now,x);
    update(node); rotate(node);  
}
int main()
{
    int n=read();
    root=new_Node(1e8,1,0,0);
    while(n--)
    {
        int op,x;
        op=read();x=read();
        switch(op)
        {
            case 1:insert(root,x);break;
            case 2:del(root,x);break;
            case 3:printf("%d\n",rank(root,x));break;
            case 4:printf("%d\n",find(root,x));break;
            case 5:printf("%d\n",find(root,rank(root,x)-1));break;
            case 6:printf("%d\n",find(root,rank(root,x+1)));break;
        }
    }
    return 0;
}

下面是合并与分裂操作(文艺平衡树)

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#define la tree[a].l
#define lb tree[b].l
#define ra tree[a].r
#define rb tree[b].r
#define ls tree[node].l
#define rs tree[node].r
#define mp make_pair
#define mix(a,b) new_Node(tree[b].value,tree[a].size+tree[b].size,0,a,b)
using namespace std;
const int maxN=7e6 + 100,ratio=4;
struct leafy
{
    int value,size;
    bool tag;
    int l,r;
}tree[maxN+1];
int n,m,cnt,root;
typedef pair<int,int> pii;
int read()
{
    int num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) num=(num<<3)+(num<<1)+(ch^48),ch=getchar();
    return num*f;
}
int new_Node(int value,int size,int tag,int l,int r)
{
    tree[++cnt]=(leafy){value,size,tag,l,r};
    return cnt;
}
void update(int node)
{
    if(!ls) {tree[node].size=1; return;}
    tree[node].size=tree[ls].size+tree[rs].size; tree[node].value=tree[rs].value;
}
void pushdown(int node)
{
    if(ls&&tree[node].tag)
    {
        swap(ls,rs);
        tree[ls].tag^=1; tree[rs].tag^=1;
        tree[node].tag=0;
    }
}
int merge(int a,int b)//max_a<min_b
{
    if(!a||!b) return a|b;
    if(max(tree[a].size,tree[b].size)<=ratio*min(tree[a].size,tree[b].size)) return mix(a,b);
    if(tree[a].size>=tree[b].size)
    {
        pushdown(a);
        if(tree[ra].size+tree[b].size<=tree[la].size*ratio) return merge(la,merge(ra,b));
        else {pushdown(ra); return merge(merge(la,tree[ra].l),merge(tree[ra].r,b));}
    }
    else
    {
        pushdown(b);
        if(tree[lb].size+tree[a].size<=tree[rb].size*ratio) return merge(merge(a,lb),rb);
        else {pushdown(lb); return merge(merge(a,tree[lb].l),merge(tree[lb].r,rb));}
    }
}
pii split(int node,int x)
{
    if(!x) return mp(0,node);
    if(!ls) return mp(node,0);
    pushdown(node);
    pii tmp;
    if(x<=tree[ls].size) {tmp=split(ls,x); return mp(tmp.first,merge(tmp.second,rs));}
    else {tmp=split(rs,x-tree[ls].size); return mp(merge(ls,tmp.first),tmp.second); }
}
void reverse(int l,int r)
{
    pii a,b;
    a=split(root,l-1); b=split(a.second,r-l+1);
    tree[b.first].tag^=1;
    root=merge(a.first,merge(b.first,b.second));
}
void build(int &node,int l,int r)
{
    node=++cnt;
    if(l==r) {tree[node].size=1; tree[node].value=l; return;}
    int mid=(l+r)>>1;
    build(ls,l,mid); build(rs,mid+1,r);
    update(node);
}
void print(int node)
{
    pushdown(node);
    if(ls) print(ls),print(rs);
    else printf("%d ",tree[node].value);
}
int main()
{
    n=read(),m=read();
    build(root,1,n);
    while(m--)
    {
        int l=read(),r=read();
        reverse(l,r);
    }
    print(root);
    return 0;
}

这是……树套树,也就是二逼平衡树qwq:

#include<cstdio>
#include<iostream>
#define ls tree[node].l
#define rs tree[node].r
#define mix(a,b) new_Node(tree[b].value,tree[a].size+tree[b].size,a,b)
using namespace std;
const int maxN=5e6 + 100,ratio=4;
struct Node
{
    int value,size;
    int l,r;
}tree[maxN*2+1];
int cnt=0,n,m,a[maxN+1];
int read()
{
    int num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch==‘-‘) f=-1; ch=getchar();}
    while(isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48),ch=getchar();
    return num*f;
}
int new_Node(int value,int size,int l,int r)
{
    tree[++cnt]=(Node){value,size,l,r};
    return cnt;
}
void update(int node)
{
    if(!ls) {tree[node].size=1; return;}
    tree[node].size=tree[ls].size+tree[rs].size; tree[node].value=tree[rs].value;
}
void rotate(int node)
{
    if(tree[ls].size>tree[rs].size*ratio) rs=mix(tree[ls].r,rs),ls=tree[ls].l;
    if(tree[rs].size>tree[ls].size*ratio) ls=mix(ls,tree[rs].l),rs=tree[rs].r;
}
int find(int node,int x)
{
    if(tree[node].size==1) return tree[node].value;
    if(x>tree[ls].size) return find(rs,x-tree[ls].size);
    else return find(ls,x);
}
int rk(int node,int x)
{
    if(tree[node].size==1) return 0;
    if(x>tree[ls].value) return tree[ls].size+rk(rs,x);
    else return rk(ls,x);
}
void insert(int node,int x)
{
    if(tree[node].size==1) ls=new_Node(min(tree[node].value,x),1,0,0),rs=new_Node(max(tree[node].value,x),1,0,0);
    else insert(x>tree[ls].value?rs:ls,x);
    update(node); rotate(node);
}
void del(int node,int x)
{
    int now,other;
    if(x>tree[ls].value) now=rs,other=ls;
    else now=ls,other=rs;
    if(tree[now].size==1)
       if(tree[now].value==x) tree[node].value=tree[other].value,tree[node].l=tree[other].l,tree[node].r=tree[other].r;
       else return;
    else del(now,x);
    update(node); rotate(node);
}
int pre(int node,int x)
{
    if(!node) return -2147483647;
    if(tree[ls].value<x) return max(ls?tree[ls].value:-2147483647,pre(rs,x));
    else return pre(ls,x);
}
int nxt(int node,int x)
{
    if(!node) return 2147483647;
    if(tree[ls].value>x) return min(ls?tree[ls].value:2147483647,nxt(ls,x));
    else return nxt(rs,x);
}

int root[maxN*4+1];
void build(int node,int l,int r)
{
    root[node]=new_Node(1e9,1,0,0);
    for(int i=l;i<=r;i++) insert(root[node],a[i]);
    if(l==r) return;
    int mid=(l+r)>>1;
    build(node<<1,l,mid);
    build(node<<1|1,mid+1,r);
}
void change(int node,int l,int r,int x,int num,int last)
{
    insert(root[node],num);
    del(root[node],last);
    if(l==r) return;
    int mid=(l+r)>>1;
    if(x<=mid) change(node<<1,l,mid,x,num,last);
    else change(node<<1|1,mid+1,r,x,num,last);
}
int query_kth(int node,int l,int r,int x,int y,int num)
{
    if(x<=l&&r<=y) return rk(root[node],num);
    int mid=(l+r)>>1,ans=0;
    if(x<=mid) ans+=query_kth(node<<1,l,mid,x,y,num);
    if(y>mid) ans+=query_kth(node<<1|1,mid+1,r,x,y,num);
    return ans;
}
int query_num(int x,int y,int num)
{
    int l=0,r=1e8,ans;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(query_kth(1,1,n,x,y,mid)+1<=num) l=mid+1,ans=mid;
        else r=mid-1;
    }
    return ans;
}
int query_pre(int node,int l,int r,int x,int y,int num)
{
    if(x<=l&&r<=y) return pre(root[node],num);
    int mid=(l+r)>>1,ans=-2147483647;
    if(x<=mid) ans=max(ans,query_pre(node<<1,l,mid,x,y,num));
    if(y>mid) ans=max(ans,query_pre(node<<1|1,mid+1,r,x,y,num));
    return ans;
}
int query_nxt(int node,int l,int r,int x,int y,int num)
{
    if(x<=l&&r<=y) return nxt(root[node],num);
    int mid=(l+r)>>1,ans=2147483647;
    if(x<=mid) ans=min(ans,query_nxt(node<<1,l,mid,x,y,num));
    if(y>mid) ans=min(ans,query_nxt(node<<1|1,mid+1,r,x,y,num));
    return ans;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    build(1,1,n);
    while(m--)
    {
        int op=read(),x,y,num;
        switch(op)
        {
            case 1:x=read(),y=read(),num=read(),printf("%d\n",query_kth(1,1,n,x,y,num)+1);break;
            case 2:x=read(),y=read(),num=read(),printf("%d\n",query_num(x,y,num));break;
            case 3:x=read(),num=read(),change(1,1,n,x,num,a[x]),a[x]=num;break;
            case 4:x=read(),y=read(),num=read(),printf("%d\n",query_pre(1,1,n,x,y,num));break;
            case 5:x=read(),y=read(),num=read(),printf("%d\n",query_nxt(1,1,n,x,y,num));break;
        }
    }
    return 0;
}

leafy tree

标签:lse   swa   ever   ++   har   name   upd   排名   print   

原文地址:https://www.cnblogs.com/cmwqf/p/10175545.html

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