2019.03.28 bzoj3595: [Scoi2014]方伯伯的Oj(splay+map+set)
传送门
题意简述:
给一个有优先级的nnn个人的序列,初始的时候第iii个人排名为iii,现在有mmm个操作,种类如下:
- 把编号为xxx的改成yyy,输出改前xxx的排名
- 把编号为xxx放到队首,输出改前xxx的排名
- 把编号为xxx放到队尾,输出改前xxx的排名
- 输出排名为xxx的编号。
强制在线,n≤1e8,m≤1e5n\le1e8,m\le1e5n≤1e8,m≤1e5
思路:
本蒟蒻的第一道splay!splay!splay!过了好激动qwqqwqqwq
由于nnn较大直接上平衡树ttt飞,考虑到操作数少,如果我们把未修改的段压成一个点然后用splaysplaysplay维护,每次就只会最多把一个分成333个,最终节点数只有3e53e53e5个就可以过了,于是用setsetset和mapmapmap辅助维护一下即可。
注意细节。
然而博主的常数太大bzoj过不了,实测1s能跑过
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=3e5+5;
typedef pair<int,int> pii;
map<pii,int>S;
map<int,int>mp,imp;
set<int>upd;
typedef set<int>::iterator It;
int n,m,tt=1;
namespace Splay{
#define lc (son[p][0])
#define rc (son[p][1])
int tot=0,rt=0,fa[N],son[N][2],L[N],R[N],siz[N],sum[N];
inline int which(const int&x){return x==son[fa[x]][1];}
inline void pushup(int p){siz[p]=siz[lc]+1+siz[rc],sum[p]=sum[lc]+(R[p]-L[p]+1)+sum[rc];}
inline int build(int l,int r,int ft,int t){
fa[++tot]=ft,ft?son[ft][t]=tot:0;
son[tot][0]=son[tot][1]=0,S[pii(l,r)]=tot;
siz[tot]=1,sum[tot]=(R[tot]=r)-(L[tot]=l)+1;
return tot;
}
inline void rotate(int x){
int y=fa[x],z=fa[y],t=which(x);
if(z)son[z][which(y)]=x;
fa[x]=z,fa[y]=x,son[y][t]=son[x][t^1],son[x][t^1]=y;
if(son[y][t])fa[son[y][t]]=y;
pushup(y),pushup(x);
}
inline void splay(int x,int ff=0){
while(fa[x]!=ff){
if(fa[fa[x]]!=ff)rotate(which(x)==which(fa[x])?fa[x]:x);
rotate(x);
}
if(!ff)rt=x;
}
inline void insert(int l,int r,int k){
--k;
int p=rt,ft=0,t;
while(p){
ft=p;
if(siz[lc]>=k)p=lc,t=0;
else k-=siz[lc]+1,p=rc,t=1;
}
splay(build(l,r,ft,t));
}
inline int pre(int p){
splay(p),p=lc;
while(rc)p=rc;
return splay(p),p;
}
inline int suf(int p){
splay(p),p=rc;
while(lc)p=lc;
return splay(p),p;
}
inline void delet(int p){
int pr=pre(p),su=suf(p);
splay(pr),splay(su,pr),son[su][0]=0,splay(su);
}
inline void init(){
insert(0,0,1),insert(1,n,2),insert(n+1,n+1,3);
upd.insert(0),upd.insert(n+1);
}
inline int update(int x,int y){
int l,r,t=mp[x]?mp[x]:x,p,ret;
mp[y]=mp[x]?mp[x]:x,imp[mp[y]]=y,mp.erase(x);
It ir=upd.lower_bound(t),il;
if(*ir==t)splay(p=S[pii(t,t)]),ret=sum[lc];
else{
il=ir;
while(*ir<t)++ir;
while(*il>t)--il;
l=*il+1,r=*ir-1;
splay(p=S[pii(l,r)]),ret=sum[lc]+t-l;
}
return ret;
}
inline int Pre(int x){
int l,r,t=mp[x]?mp[x]:x,p,ret,rk;
It ir=upd.lower_bound(t),il;
if(*ir==t){
splay(p=S[pii(t,t)]),ret=sum[lc];
delet(p),insert(t,t,2);
}
else{
il=ir;
while(*ir<t)++ir;
while(*il>t)--il;
l=*il+1,r=*ir-1,splay(p=S[pii(l,r)]),ret=sum[lc]+t-l,rk=siz[lc]+1;
upd.insert(t);
delet(p);
if(t==l)insert(t+1,r,rk);
else if(t==r)insert(l,t-1,rk);
else insert(l,t-1,rk),insert(t+1,r,rk+1);
insert(t,t,2);
}
return ret;
}
inline int Suf(int x){
int l,r,t=mp[x]?mp[x]:x,p,ret,rk;
It ir=upd.lower_bound(t),il;
if(*ir==t){
splay(p=S[pii(t,t)]),ret=sum[lc];
delet(p),insert(t,t,siz[rt]);
}
else{
il=ir;
while(*ir<t)++ir;
while(*il>t)--il;
l=*il+1,r=*ir-1,splay(p=S[pii(l,r)]),ret=sum[lc]+t-l,rk=siz[lc]+1;
upd.insert(t);
delet(p);
if(t==l)insert(t+1,r,rk);
else if(t==r)insert(l,t-1,rk);
else insert(l,t-1,rk),insert(t+1,r,rk+1);
insert(t,t,siz[rt]);
}
return ret;
}
inline int Rank(int k){
++k;
int p=rt,ret;
while(p){
if(sum[lc]>=k)p=lc;
else if(sum[lc]+R[p]-L[p]+1>=k){
ret=L[p]+(k-sum[lc])-1;
break;
}
else k-=sum[lc]+R[p]-L[p]+1,p=rc;
}
return !imp[ret]?ret:imp[ret];
}
#undef lc
#undef rc
}
int main(){
n=read(),m=read();
Splay::init();
for(ri x,y,lastans=0,op;m;--m,++tt){
op=read();
switch(op){
case 1:{x=read()-lastans,y=read()-lastans,lastans=Splay::update(x,y);break;}
case 2:{x=read()-lastans,lastans=Splay::Pre(x);break;}
case 3:{x=read()-lastans,lastans=Splay::Suf(x);break;}
case 4:{x=read()-lastans,lastans=Splay::Rank(x);break;}
}
cout<<lastans<<'\n';
}
return 0;
}
2019.03.28 bzoj3595: [Scoi2014]方伯伯的Oj(splay+map+set)的更多相关文章
- 2019.03.28 bzoj3597: [Scoi2014]方伯伯运椰子(01分数规划)
传送门 题意咕咕咕有点麻烦不想写 思路: 考虑加了多少一定要压缩多少,这样可以改造边. 于是可以通过分数规划+spfaspfaspfa解决. 代码: #include<bits/stdc++.h ...
- 2019.03.28 bzoj3594: [Scoi2014]方伯伯的玉米田(二维bit优化dp)
传送门 题意咕咕咕 思路:直接上二维bitbitbit优化dpdpdp即可. 代码: #include<bits/stdc++.h> #define N 10005 #define K 5 ...
- 2019.03.28 bzoj3598: [Scoi2014]方伯伯的商场之旅(带权中位数+数位dp)
传送门 题意咕咕咕自己读吧挺简单的 思路: 由带权中位数的性质可以得到对于每个数放在每个二进制位的代价一定是个单调或者单峰函数,因此我们先把所有的数都挪到第一个位置,然后依次向右枚举峰点(极值点)把能 ...
- luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树
LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...
- BZOJ 3595: [Scoi2014]方伯伯的Oj Splay + 动态裂点 + 卡常
Description 方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题. Oj上注册了n个用户,编号为1-”,一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和 ...
- [BZOJ3595][SCOI2014]方伯伯的OJ(裂点Splay)
用一棵Splay按名次维护每个点,其中一个节点对应初始编号连续的一段区间,这样总节点数是$O(m)$的. 对每个编号记录这个点被Splay的那个节点维护,用std::map存储,只记录被修改的点. 每 ...
- BZOJ3595 : [Scoi2014]方伯伯的Oj
由于n很大,有2e8,所以不能直接用splay来维护排名 把splay修改一下 每个节点维护一个区间[l,r],表示编号在[l,r]之间的所有点都在这里 需要支持一个takeout操作: 把编号为k的 ...
- BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap
3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec Memory Limit: 256 MBSubmit: 102 Solved: 54[Submit][Status ...
- 洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树
洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树 题目描述 方伯伯正在做他的 \(Oj\) .现在他在处理 \(Oj\) 上的用户排名问题. \(Oj\) 上注册了 \(n\) 个用户 ...
随机推荐
- Linux安装Tomcat,运行Eclipse,web项目
到官网下载:https://tomcat.apache.org/download-80.cgi 在这里是8.5.39版本 下载tar,gz 提取解压后,我这里是放到opt目录下 cd 切换目录 / ...
- 项目(七)SVN版本管理与大型代码上线方案
SVN介绍 Svn(subversion)是近年来崛起的非常优秀的版本管理工具,与CVS管理工具一样,SVN是一个跨平台的开源的版本控制系统.Svn版本管理工具管理着随时间改变的各种数据.这些数据放置 ...
- PS 知识整理
Ctrl+J键复制背景图层. ps怎样只让截取的一部分图旋转 https://jingyan.baidu.com/article/d45ad14877fc6e69542b8079.html 按Ctrl ...
- 提高GitHub下载速度
修改/etc/hosts 加上 151.101.72.249 GitHub.global.ssl.fastly.net 192.30.253.112 github.com
- Charles篡改后台数据
1.打开Charles找到相对应的接口 2.在接口上右键选择Breakpoints打断点. 3.重新请求截断接口,Charles会多弹出一个截断窗口如下图(第一个修改请求的,第二图是修改返回的) 点击 ...
- GCC后端移植杂记
为GCC后端移植新的处理器架构的确是一件非常痛苦的事情. 拿到GCC源码时,发现它的规模比预想中庞大得多,但好在体系结构十分清晰,前端后端高度解耦.解耦的关键就在于内部的RTL中间代码(表达形式类似于 ...
- centos7下Etcd3集群搭建
一.环境介绍 etcd主要功能是分布式的存储键值,优点不多说了,分布是集群,自动选举等等,自行百度,主要说下配置方法,折腾了几天,终于优点眉目了,记录下操作方法,本文参考了如下链接 https://w ...
- POJ-3660.Cow Contest(有向图的传递闭包)
Cow Contest Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17797 Accepted: 9893 De ...
- PowerScript SQL语句
PowerScript支持在脚本中使用标准的嵌入式SQL和动态SQL语句.还支持在SQL语句中使用数据库管理系统的语句.函数和保留字. 在SQL中任何地点都可以使用常量和任何合法的变量,但使用变量时必 ...
- bootloaderd的再解析
boot的0脚和1脚可以选择启动方式,以前只知道可以选择的方式是nandflash启动,或者选择从norflash启动,当选择nandflash启动时,cpu看到的0地址是ram的0地址,根据是nan ...