博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二逼平衡树 题解(树套树)
阅读量:5037 次
发布时间:2019-06-12

本文共 4928 字,大约阅读时间需要 16 分钟。

我 想 扇 死 自 己

void up(int x)    {        if(x)        {            size[x]=cnt[x];//我TM这行忘了            if(son[x][0])size[x]+=size[son[x][0]];            if(son[x][1])size[x]+=size[son[x][1]];        }    }

4个小时!调一道模板!我敲里码!

上道splay刚因为细节打错浪费了3个小时时间,这次就又**重现了

不多说了,先把splay抄上10遍,手写!

-----------以下是正经题解----------------

第一道树套树:线段树套splay

对于线段树的每一段区间建splay维护这段的信息

在合并时:

排名相加;

前驱取max;

后继取min;

 

比较麻烦的是查询数值,需要二分答案.

以数值为值域进行二分,不断询问mid的排名来缩小范围。

 

#include
#include
#include
#include
using namespace std;const int N=4000005,inf=1e9;int n,m,a[N]; int root[N],son[N][3],fa[N],key[N],size[N],type,cnt[N]; void clear(int x) { if(!x)return ; fa[x]=cnt[x]=son[x][0]=son[x][1]=size[x]=key[x]=0; } int pre(int k) { int now=son[root[k]][0]; while(son[now][1])now=son[now][1]; return now; } bool judge(int x) { return son[fa[x]][1]==x; } void up(int x) { if(x) { size[x]=cnt[x]; if(son[x][0])size[x]+=size[son[x][0]]; if(son[x][1])size[x]+=size[son[x][1]]; } } void rotate(int x) { int old=fa[x],oldf=fa[old],lr=judge(x); son[old][lr]=son[x][lr^1]; fa[son[old][lr]]=old; son[x][lr^1]=old; fa[old]=x; fa[x]=oldf; if(oldf)son[oldf][son[oldf][1]==old]=x; up(old);up(x); } void splay(int k,int x) { for(int f;f=fa[x];rotate(x)) if(fa[f])rotate(judge(x)==judge(f)?f:x); root[k]=x; } void ins(int k,int x) { if(!root[k]) { type++; key[type]=x; root[k]=type; cnt[type]=size[type]=1; fa[type]=son[type][0]=son[type][1]=0; return ; } int now=root[k],f=0; while(1) { if(x==key[now]) { cnt[now]++; up(now); up(f); splay(k,now); return ; } f=now;now=son[now][key[now]
key[f]]=type; fa[type]=f; key[type]=x; up(f);splay(k,type); return ; } } } int getrank(int k,int x) { int now=root[k],ans=0; while(1) { if(!now)return ans; if(x==key[now])return (son[now][0]?size[son[now][0]]:0)+ans; else if(x>key[now]) { ans+=(son[now][0]?size[son[now][0]]:0)+cnt[now]; now=son[now][1]; } else if(x
x) { if(ans>key[now])ans=key[now]; now=son[now][0]; } else now=son[now][1]; } return ans; } void del(int k,int x) { int now=findpos(k,x); splay(k,now); if(cnt[root[k]]>1) { cnt[root[k]]--; up(root[k]); return ; } else if(!son[root[k]][0]&&(!son[root[k]][1])) { clear(root[k]); root[k]=0; return ; } int old=root[k]; if(son[root[k]][0]*son[root[k]][1]==0) { if(!son[root[k]][0])root[k]=son[root[k]][1]; else root[k]=son[root[k]][0]; fa[root[k]]=0; clear(old); return ; } int L=pre(k); splay(k,L); son[root[k]][1]=son[old][1]; fa[son[old][1]]=root[k]; clear(old); up(root[k]); } #define ls(k) k<<1 #define rs(k) k<<1|1 void update(int k,int l,int r,int pos,int val) { ins(k,val); if(l==r)return ; int mid=l+r>>1; if(pos<=mid)update(ls(k),l,mid,pos,val); else update(rs(k),mid+1,r,pos,val); return ; } int rank(int k,int l,int r,int L,int R,int val) { if(l>=L&&r<=R) { int res=getrank(k,val); return res; } int mid=l+r>>1,res=0; if(L<=mid)res+=rank(ls(k),l,mid,L,R,val); if(R>mid)res+=rank(rs(k),mid+1,r,L,R,val); return res; } void modify(int k,int l,int r,int pos,int val) { del(k,a[pos]); ins(k,val); if(l==r)return ; int mid=l+r>>1; if(pos<=mid)modify(ls(k),l,mid,pos,val); else modify(rs(k),mid+1,r,pos,val); } int getpre(int k,int l,int r,int L,int R,int val) { if(l>=L&&r<=R)return findpre(k,val); int mid=l+r>>1,res=0; if(L<=mid)res=max(res,getpre(ls(k),l,mid,L,R,val)); if(R>mid)res=max(res,getpre(rs(k),mid+1,r,L,R,val)); return res; } int getnxt(int k,int l,int r,int L,int R,int val) { if(l>=L&&r<=R)return findnxt(k,val); int mid=l+r>>1,res=inf; if(L<=mid)res=min(res,getnxt(ls(k),l,mid,L,R,val)); if(R>mid)res=min(res,getnxt(rs(k),mid+1,r,L,R,val)); return res; }inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f;}int main(){ n=read();m=read(); int op,maxx=0; for(int i=1;i<=n;i++) { a[i]=read(); update(1,1,n,i,a[i]); maxx=max(maxx,a[i]); } while(m--) { op=read(); if(op==1) { int l=read(),r=read(),val=read(); printf("%d\n",rank(1,1,n,l,r,val)+1); } else if(op==2) { int l=read(),r=read(),val=read(); int L=0,R=maxx+1; while(L!=R) { int mid=L+R>>1; int res=rank(1,1,n,l,r,mid); //cout<<"***"<
<

 

转载于:https://www.cnblogs.com/Rorschach-XR/p/11019342.html

你可能感兴趣的文章
KRPano动态热点专用素材图50多个,加动态热点使用方法
查看>>
yii模型ar中备忘
查看>>
C#线程入门
查看>>
CSS清除浮动方法
查看>>
JVM内存回收机制简述
查看>>
洛咕 P2480 [SDOI2010]古代猪文
查看>>
js-创建对象的几种方式
查看>>
JDK JRE Java虚拟机的关系
查看>>
2018.11.20
查看>>
word20161215
查看>>
12th week blog
查看>>
dijkstra (模板)
查看>>
python小记(3)
查看>>
编译Linux驱动程序 遇到的问题
查看>>
大型分布式网站架构技术总结
查看>>
HDU 1017[A Mathematical Curiosity]暴力,格式
查看>>
[算法之美] KMP算法的直观理解
查看>>
EntityFramework 性能优化
查看>>
基于LBS功能,Geohash在PHP中运用实例
查看>>
NoClassDefFoundError: org.ksoap2.transport.HttpTransportSE
查看>>