洛谷 P3285 / loj 2212 [SCOI2014] 方伯伯的 OJ 题解【平衡树】【线段树】
平衡树分裂钛好玩辣!
题目描述
方伯伯正在做他的 OJ。现在他在处理 OJ 上的用户排名问题。
OJ 上注册了 \(n\) 个用户,编号为 \(1\sim n\),一开始他们按照编号排名。方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和编号:
- 操作格式为
1 x y
,意味着将编号为 \(x\) 的用户编号改为 \(y\),而排名不变,执行完该操作后需要输出该用户在排名中的位置,数据保证 \(x\) 必然出现在排名中,同时 \(y\) 是一个当前不在排名中的编号。- 操作格式为
2 x
,意味着将编号为 \(x\) 的用户的排名提升到第一位,执行完该操作后需要输出执行该操作前编号为 \(x\) 用户的排名。- 操作格式为
3 x
,意味着将编号为 \(x\) 的用户的排名降到最后一位,执行完该操作后需要输出执行该操作前编号为 \(x\) 用户的排名。- 操作格式为
4 k
,意味着查询当前排名为 \(k\) 的用户编号,执行完该操作后需要输出当前操作用户的编号。 但同时为了防止别人监听自己的工作,方伯伯对他的操作进行了加密,即将四种操作的格式分别改为了:1 x+a y+a
2 x+a
3 x+a
4 k+a
其中 \(a\) 为上一次操作得到的输出,一开始 \(a=0\)。
例如: 上一次操作得到的输出是
5
,
这一次操作的输入为:1 13 15
,
因为这个输入是经过加密后的,所以你应该处理的操作是1 8 10
。现在你截获了方伯伯的所有操作,希望你能给出结果。
输入输出格式
输入格式:
输入的第一行包含两个用空格分隔的整数 \(n\) 和 \(m\),表示初始用户数和操作数。
此后有 \(m\) 行,每行是一个询问,询问格式如上所示。
输出格式:
输出包含 \(m\) 行。每行包含一个整数,其中第 \(i\) 行的整数表示第 \(i\) 个操作的输出。
输入输出样例
输入样例:
10 10
1 2 11
3 13
2 5
3 7
2 8
2 10
2 11
3 14
2 18
4 9
输出样例:
2
2
2
4
3
5
5
7
8
11
数据范围与说明
对于 \(100\%\) 的数据,\(1\le n\le 10^8,\ 1\le m\le 10^5\)。
输入保证对于所有的操作,\(x\) 必然已经出现在队列中,同时对于所有操作
1
,\(1\le y\le 2\times 10^8\),并且 \(y\) 没有出现在队列中。对于所有操作
4
,保证 \(1\le k\le n\)。
题解:
平衡树”区间移动“题。
用带点分裂的 fhq Treap 移动区间,用线段树维护区间内元素在平衡树上的数组下标。
在平衡树上保留父亲信息。其中fa[root]=0
,然后就可以顺着爬上去来计算每个节点的排名。
时间复杂度 \(O(m\log n)\)。
Code:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define len(x) (r[x]-l[x]+1)
#define mid ((L+R)>>1)
#define N 200000000
namespace sgt
{
int ls[6000000],rs[6000000],v[6000000],lazy[6000000],pcnt=1;
void pushdown(int k,int L,int R)
{
if(!lazy[k]||L==R)
return;
int x=lazy[k];
v[ls[k]]=x;
lazy[ls[k]]=x;
v[rs[k]]=x;
lazy[rs[k]]=x;
lazy[k]=0;
return;
}
void change(int k,int l,int r,int L,int R,int x)//把区间[l,r]改成x
{
if(l<=L&&r>=R)
{
v[k]=x;
lazy[k]=x;
return;
}
if(r<L||l>R)
return;
if(!ls[k])
ls[k]=++pcnt;
if(!rs[k])
rs[k]=++pcnt;
pushdown(k,L,R);
change(ls[k],l,r,L,mid,x);
change(rs[k],l,r,mid+1,R,x);
}
int ask(int k,int p,int L,int R)//求点i的编号
{
if(!ls[k]&&!rs[k])
return v[k];
pushdown(k,L,R);
if(p<=mid)
return ask(ls[k],p,L,mid);
return ask(rs[k],p,mid+1,R);
}
}
int root=0;
namespace bst
{
int rdm[200100],ls[200100],rs[200100],fa[200100];
int sz[200100],l[200100],r[200100];
int pcnt=0;
int Newnode(int L,int R)
{
++pcnt;
l[pcnt]=L;
r[pcnt]=R;
sz[pcnt]=R-L+1;
rdm[pcnt]=rand();
sgt::change(1,L,R,1,N,pcnt);
return pcnt;
}
void maintain(int k)
{
sz[k]=sz[ls[k]]+sz[rs[k]]+r[k]-l[k]+1;
fa[ls[k]]=k;
fa[rs[k]]=k;
}
int Merge(int a,int b)
{
if(!a||!b)
return a|b;
if(rdm[a]<rdm[b])
{
rs[a]=Merge(rs[a],b);
maintain(a);
return a;
}
ls[b]=Merge(a,ls[b]);
maintain(b);
return b;
}
void split(int rt,int x,int &a,int &b)
{
if(!rt)
{
a=0,b=0;
return;
}
int L=sz[ls[rt]],R=r[rt]-l[rt]+1;
if(x<=L)
{
b=rt;
split(ls[rt],x,a,ls[b]);
}
else if(x<L+R)
{
x-=L;
a=rt;
b=Newnode(l[rt]+x,r[rt]);
r[a]=l[rt]+x-1;
rs[b]=rs[a];
rs[a]=0;
maintain(a);
maintain(b);
return;
}
else
{
a=rt;
split(rs[rt],x-L-R,rs[a],b);
}
maintain(rt);
}
int Rank(int p)
{
int k=sgt::ask(1,p,1,N);
int ans=sz[ls[k]]+p-l[k]+1;
while(fa[k])
{
if(k==rs[fa[k]])
ans+=sz[ls[fa[k]]]+len(fa[k]);
k=fa[k];
}
return ans;
}
}
int main()
{
int n,m,op,x,y,z=0;
int a,b,c;
scanf("%d%d",&n,&m);
root=bst::Newnode(1,n);
while(m--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d",&x,&y);
x-=z,y-=z;
z=bst::Rank(x);
printf("%d\n",z);
bst::split(root,z-1,a,b);
bst::split(b,1,b,c);
bst::l[b]=bst::r[b]=y;
sgt::change(1,y,y,1,N,b);
root=bst::Merge(bst::Merge(a,b),c);
bst::fa[root]=0;
}
else if(op==2||op==3)
{
scanf("%d",&x);
x-=z;
z=bst::Rank(x);
printf("%d\n",z);
bst::split(root,z-1,a,b);
bst::split(b,1,b,c);
if(op==2)
root=bst::Merge(bst::Merge(b,a),c);
else
root=bst::Merge(bst::Merge(a,c),b);
bst::fa[root]=0;
}
else
{
scanf("%d",&x);
x-=z;
bst::split(root,x-1,a,b);
bst::split(b,1,b,c);
z=bst::l[b];
printf("%d\n",z);
root=bst::Merge(bst::Merge(a,b),c);
bst::fa[root]=0;
}
}
return 0;
}
洛谷 P3285 / loj 2212 [SCOI2014] 方伯伯的 OJ 题解【平衡树】【线段树】的更多相关文章
- 洛谷 P3285 - [SCOI2014]方伯伯的OJ(平衡树)
洛谷题面传送门 在酒店写的,刚了一整晚终于调出来了-- 首先考虑当 \(n\) 比较小(\(10^5\) 级别)的时候怎么解决,我们考虑将所有用户按排名为关键字建立二叉排序树,我们同时再用一个 map ...
- 洛谷P4458 /loj#2512.[BJOI2018]链上二次求和(线段树)
题面 传送门(loj) 传送门(洛谷) 题解 我果然是人傻常数大的典型啊-- 题解在这儿 //minamoto #include<bits/stdc++.h> #define R regi ...
- 洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树
洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树 题目描述 方伯伯正在做他的 \(Oj\) .现在他在处理 \(Oj\) 上的用户排名问题. \(Oj\) 上注册了 \(n\) 个用户 ...
- BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap
3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec Memory Limit: 256 MBSubmit: 102 Solved: 54[Submit][Status ...
- 洛谷 P3919 【模板】可持久化数组(可持久化线段树/平衡树)-可持久化线段树(单点更新,单点查询)
P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目背景 UPDATE : 最后一个点时间空间已经放大 标题即题意 有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集 ...
- 洛谷 P4125 [WC2012]记忆中的水杉树【扫描线+set+线段树】
我没有找到能在bzojAC的代码--当然我也WA了--但是我在洛谷过了,那就假装过了吧 minmax线段树一开始写的只能用min更新min,max更新max,实际上是可以互相更新的-- 首先看第二问, ...
- luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树
LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...
- 洛谷 P3285 [SCOI2014]方伯伯的OJ
看到这题,第一眼:平衡树水题,随便做一做好了 然后....我在花了n个小时去调试(维护平衡树父节点)之后,... 调了三个小时后,第一次失败的代码(只能查找排名为k的用户编号,不能根据编号查排名) # ...
- [SCOI2014]方伯伯的OJ(线段树)
方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题.Oj上注册了n个用户,编号为1-n“,一开始他们按照编号排名. 方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和编号: 1.操作格式为 ...
随机推荐
- Mysql加载本地CSV文件
Mysql加载本地CSV文件 1.系统环境 系统版本:Win10 64位 Mysql版本: 8.0.15 MySQL Community Server - GPL Mysql Workbench版本: ...
- CEPH集群RBD快照创建、恢复、删除、克隆(转)
Ceph支持一个非常好的特性,以COW(写时复制)的方式从RBD快照创建克隆,在Ceph中被称为快照分层.分层特性允许用户创建多个CEPH RBD克隆实例.这些特性应用于OpenStack等云平台中 ...
- git post-receive
1. 将 www 目录设为 777 2. 用git 用户 mkdir 并 git init 3. cat id_rsa.pub >. authorkeys
- 编写高质量代码改善C#程序的157个建议——建议65:总是处理未捕获的异常
建议65:总是处理未捕获的异常 处理为捕获的异常是每个应用程序具备的基本功能,C#在APPDomain提供了UnhandledException事件来接收未捕获到的异常的通知.常见的应用如下: sta ...
- Linux或者window装svn
Centos7搭建SVN Server手记 安装svn和依赖模块 yum install httpd httpd-devel subversion mod_dav_svn mod_auth_mysql ...
- jmeter- 性能测试3:聚合报告(Aggregate Report )
jmeter-监听器-聚合报告样例: 字段说明: label:请求名称,自己定义的 #Samples:这次测试中一共发出了多少个请求,如果模拟20个用户,每个用户迭代20次,那么就是400(未设置持续 ...
- HTML5+CSS3+jQuery Mobile轻松构造APP与移动网站 (陈婉凌) 中文pdf扫描版
<HTML5+CSS3+jQuery Mobile轻松构造APP与移动网站>以HTML与CSS为主,配合jQuery制作网页,并搭配jQueryMobile制作移动网页,通过具体的范例从基 ...
- [Mac] 获取cpu信息
[Mac] 获取cpu信息 命令行获取cpu信息 sysctl machdep.cpu output like machdep.cpu.tsc_ccc.denominator: 0 machdep.c ...
- 数独高阶技巧之八——SDC
在本系列的第四篇“简单异数链”中,向大家介绍了XY-Wing等一系列Wing类技巧,并提到可以用(拐弯的)数组的观念来理解这些结构,经过第六篇ALS的学习之后,大家回过头再去看Wing,应该可以发现相 ...
- Java Spring Bean相关配置
1.Bean配置信息组成部分: (1)Bean实现类 (2)Bean的属性信息 (3)Bean的依赖关系 (4)Bean的行为配置 2.配置方式: (1)XML配置 (2)注解配置 (3)Java类配 ...