浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html

浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html

题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=2028

此题的线段树写法:https://www.cnblogs.com/AKMer/p/9948789.html

我如果要插入一个新的区间\([l,r]\),会被这个预约冲掉的区间显然满足\(st\leqslant r\)且\(ed\geqslant l\)。对于这样的预约是连续的一段,于是我们就可以通过区间删除来达到踢出预约的效果了。那么怎么找这连续的一段区间呢?

对于\(splay\)

将结束时间严格小于\(l\)的预约旋到根,将起始时间严格大于\(r\)的预约旋到根的右儿子。那么根的右儿子的左子树里所有的预约就都是会被当前预约冲掉的预约,直接全部删掉就行了。

对于\(fhq\)_\(treap\)

将整个树分成三部分,第一部分满足所有结点结束时间严格小于\(l\),第三部分满足所有结点起始时间严格大于\(l\),然后直接把第二部分换成代表新的预约的结点\(merge\)起来就行了。

时间复杂度:\(O(nlogn)\)

空间复杂度:\(O(n)\)

\(splay\)版代码如下:

#include <cstdio>
using namespace std; const int maxn=2e5+5,inf=2e9; int n;
char s[5]; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct Splay {
int tot,root;
int fa[maxn],son[maxn][2];
int val[maxn][2],siz[maxn]; int newnode(int l,int r) {
siz[++tot]=1;
val[tot][0]=l,val[tot][1]=r;
return tot;
} int t(int u) {
return son[fa[u]][1]==u;
} void update(int u) {
siz[u]=siz[son[u][0]]+1+siz[son[u][1]];
} void rotate(int u) {
int ret=t(u),f=fa[u],s=son[u][ret^1];
son[f][ret]=s;if(s)fa[s]=f;son[u][ret^1]=f;
fa[u]=fa[f];if(fa[f])son[fa[f]][t(f)]=u;
fa[f]=u;update(f);update(u);
} void splay(int goal,int u) {
int tmp=fa[goal];
while(fa[u]!=tmp) {
if(fa[fa[u]]!=tmp) {
if(t(fa[u])==t(u))rotate(fa[u]);
else rotate(u);
}
rotate(u);
}
if(!tmp)root=u;
} int find(int opt,int v) {
int u=root;
while(val[u][opt]!=v) {
if(val[u][opt]<v) {if(son[u][1])u=son[u][1];else break;}
if(val[u][opt]>v) {if(son[u][0])u=son[u][0];else break;}
}
return u;
} int get_pre(int v) {
int u=find(1,v);splay(root,u);
if(val[u][1]<v)return u;
u=son[u][0];
while(son[u][1])u=son[u][1];
return u;
} int get_suc(int v) {
int u=find(0,v);splay(root,u);
if(val[u][0]>v)return u;
u=son[u][1];
while(son[u][0])u=son[u][0];
return u;
} void ins(int l,int r) {
int u=get_pre(l),v=get_suc(r);
splay(root,u);splay(son[root][1],v);
son[v][0]=newnode(l,r);fa[tot]=v;
update(v);update(u);
} void prepare() {
int a=newnode(-inf,-inf),b=newnode(inf,inf);
son[a][1]=b;fa[b]=a;update(a);root=a;
}
}T; int main() {
T.prepare();
n=read();
for(int i=1;i<=n;i++) {
scanf("%s",s+1);
if(s[1]=='B')printf("%d\n",T.siz[T.root]-2);
else {
int l=read(),r=read();
int tmp=T.siz[T.root];
T.ins(l,r);
printf("%d\n",tmp-(T.siz[T.root]-1));
}
}
return 0;
}

\(fhq\)_\(treap\)版代码如下:

#include <ctime>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii; const int maxn=2e5+5; int n;
char s[5]; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct fhq_treap {
int tot,root;
int fix[maxn],son[maxn][2];
int siz[maxn],val[maxn][2]; int newnode(int l,int r) {
fix[++tot]=rand();
val[tot][0]=l,val[tot][1]=r;
siz[tot]=1;return tot;
} void update(int u) {
siz[u]=siz[son[u][0]]+1+siz[son[u][1]];
} int find(int u,int opt,int v,int bo) {
if(!u)return 0;
int ans=0;
if(val[u][opt]>v)ans=find(son[u][0],opt,v,bo);
else if(val[u][opt]==v)return siz[son[u][0]]+bo;
else ans=siz[son[u][0]]+1+find(son[u][1],opt,v,bo);
return ans;
} pii split(int u,int rk) {
if(!rk)return make_pair(0,u);
if(rk==siz[u])return make_pair(u,0);
if(siz[son[u][0]]>=rk) {
pii tmp=split(son[u][0],rk);
son[u][0]=tmp.second,update(u);
return make_pair(tmp.first,u);
}
else {
pii tmp=split(son[u][1],rk-siz[son[u][0]]-1);
son[u][1]=tmp.first,update(u);
return make_pair(u,tmp.second);
}
} int merge(int a,int b) {
if(!a||!b)return a+b;
if(fix[a]>fix[b])return son[a][1]=merge(son[a][1],b),update(a),a;
else return son[b][0]=merge(a,son[b][0]),update(b),b;
} int ins(int l,int r) {
int rk1=find(root,0,r,1),rk2=find(root,1,l,0);
pii tmp1=split(root,rk1),tmp2=split(tmp1.first,rk2);
root=merge(merge(tmp2.first,newnode(l,r)),tmp1.second);
return siz[tmp2.second];
}
}T; int main() {
srand(time(0));n=read();
for(int i=1;i<=n;i++) {
scanf("%s",s+1);
if(s[1]=='B')printf("%d\n",T.siz[T.root]);
else {
int l=read(),r=read();
printf("%d\n",T.ins(l,r));
}
}
return 0;
}

BZOJ2028:[SHOI2009]会场预约(平衡树版)的更多相关文章

  1. BZOJ2028: [SHOI2009]会场预约(set)

    Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 425  Solved: 213[Submit][Status][Discuss] Description ...

  2. 2021.12.08 [SHOI2009]会场预约(平衡树游码表)

    2021.12.08 [SHOI2009]会场预约(平衡树游码表) https://www.luogu.com.cn/problem/P2161 题意: 你需要维护一个 在数轴上的线段 的集合 \(S ...

  3. [LuoguP2161[ [SHOI2009]会场预约 (splay)

    题面 传送门:https://www.luogu.org/problemnew/show/P2161 Solution splay 的确有线段树/树状数组的做法,但我做的时候脑残没想到 我们可以考虑写 ...

  4. 【题解】P2161[SHOI2009]会场预约(set)

    [题解][P2161 SHOI2009]会场预约 题目很像[[题解]APIO2009]会议中心 \(set\)大法好啊! 然后我们有个小\(trick\)(炒鸡帅),就是如何优雅地判断线段交? str ...

  5. SHOI 2009 会场预约 平衡树 STL练习

    题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...

  6. [SHOI2009] 会场预约 - Treap

    Description PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也 ...

  7. P2161 [SHOI2009]会场预约

    题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...

  8. P2161 [SHOI2009]会场预约 (线段树:线段树上的不重复覆盖数)

    题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...

  9. P2161 [SHOI2009]会场预约[线段树/树状数组+二分/STL]

    题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...

随机推荐

  1. JavaScript系列问题

    JavaScript系列问题:  0.javascript 基础教程[温故而知新一] 1.通过JS变更页面字体的大小 2.图片压缩优化能有效提高网站浏览速度

  2. 【虚拟机】WIN8.1系统虚拟机完全彻底删除

    一.首先删除注册表 用管理员身份打开CMD,输入F:\>VMware-workstation-full-12.5.5-5234757.exe/clean,根据自己的虚拟机安装文件的路径进行改变( ...

  3. JVM内存布局及GC知识回顾

    注:本文篇幅较长,且需要有一定的java基础,建议各位看官,备好瓜子.饮料.小板凳,摆个让自己舒服的姿势,慢慢细看^_^, 文中所有素材,均来自互联网,本人只是详细梳理了一遍,形成此文. 一.JVM运 ...

  4. T-SQL简单查询语句(模糊查询)

    T-SQL简单查询语句 简单查询: 1.最简单查询(查所有数据) select * from 表名: 注:* 代表所有列 select * from info 2.查询指定列 select code, ...

  5. android菜鸟学习笔记3----关于AndroidMainfest.xml

    每个android项目都包含一个AndroidMainfest.xml文件,它包含了组成应用程序的每一个Acitivity.Service.Content Provider和Broadcast Rec ...

  6. Error524 源站处理超时 Error 524: A timeout occurred

    https://su.baidu.com/helps/index.html#/4/5a61e4b5b34f697f13234a5b Error524 源站处理超时 更新时间:2018-01-19 20 ...

  7. php计算数组的维数

    function array_dim($arr){ if(!is_array($arr)) return 0; else{ $max1 = 0; foreach($arr as $item1){ $t ...

  8. 腾讯云上运行java程序过程

    1: 购买服务器(腾讯云,阿里云等) 2:安装centos操作系统: 3:安装jdkhttp://www.cnblogs.com/Amos-Turing/p/7403696.html 4:安装数据库( ...

  9. 阿里云ecs docker使用(3)

    进入docker后安装nodejs 1. 安装nodejs 2. 安装express-generator 3. mkdir repo && cd repo express myapp ...

  10. datetime-local设置初始值

    //全局变量 var format = ""; //构造符合datetime-local格式的当前日期 function getFormat(){ format = "& ...