标签: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;
}
标签:lse swa ever ++ har name upd 排名 print
原文地址:https://www.cnblogs.com/cmwqf/p/10175545.html