由于n很大,有2e8,所以不能直接用splay来维护排名

把splay修改一下

每个节点维护一个区间[l,r],表示编号在[l,r]之间的所有点都在这里

需要支持一个takeout操作:

把编号为k的玩家分离出来,成为一个独立的点

先找到它所在的大点x

splay(x)

然后分裂成1-3个节点

关于如何查找编号为k的玩家在splay中哪个节点

可以开一棵动态开节点的线段树来维护

每次分裂实质就是区间赋值,打标记即可

时间复杂度$O(m\log n)$

写起来真是神清气爽…

#include<cstdio>
#define N 300010
#define M 9000000
const int R=200000000;
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int ans;
struct Segmenttree{
int tot,l[M],r[M],tag[M],val[M];
inline void make1(int x,int a,int b,int p){
if(!x)return;
if(a==b)val[x]=p;else tag[x]=p;
}
inline void pb(int x,int a,int b){
if(tag[x]){
int mid=(a+b)>>1;
if(!l[x])l[x]=++tot;
if(!r[x])r[x]=++tot;
make1(l[x],a,mid,tag[x]);
make1(r[x],mid+1,b,tag[x]);
tag[x]=0;
}
}
void change(int x,int a,int b,int c,int d,int p){
if(c<=a&&b<=d){
make1(x,a,b,p);
return;
}
int mid=(a+b)>>1;
pb(x,a,b);
if(c<=mid){
if(!l[x])l[x]=++tot;
change(l[x],a,mid,c,d,p);
}
if(d>mid){
if(!r[x])r[x]=++tot;
change(r[x],mid+1,b,c,d,p);
}
}
int ask(int x,int a,int b,int c){
if(a==b)return val[x];
int mid=(a+b)>>1;
pb(x,a,b);
return c<=mid?ask(l[x],a,mid,c):ask(r[x],mid+1,b,c);
}
inline void init(){
tot=1;
make1(1,1,R,1);
}
}S;
int tot,root,f[N],son[N][2],l[N],r[N],sum[N];
inline void init(int n){
tot=root=l[1]=1;r[1]=n;
}
inline void up(int x){sum[x]=sum[son[x][0]]+sum[son[x][1]]+r[x]-l[x]+1;}
inline void setson(int x,int w,int y){son[x][w]=y;if(y)f[y]=x;}
inline void rotate(int x){
int y=f[x],w=son[y][1]==x;
son[y][w]=son[x][!w];
if(son[x][!w])f[son[x][!w]]=y;
if(f[y]){
int z=f[y];
if(son[z][0]==y)son[z][0]=x;
if(son[z][1]==y)son[z][1]=x;
}
f[x]=f[y];f[y]=x;son[x][!w]=y;up(y);
}
inline void splay(int x){
while(f[x]){
int y=f[x];
if(f[y]){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
rotate(x);
}
up(root=x);
}
inline int kth(int k){
int x=root,nl,nr;
while(1){
nl=sum[son[x][0]]+1;nr=nl+r[x]-l[x];
if(nl<=k&&k<=nr)return k-nl+l[x];
if(k<nl)x=son[x][0];
else k-=nr,x=son[x][1];
}
}
inline int takeout(int k){//将编号为k的点分离成单点
int x=S.ask(1,1,R,k);
splay(x);
int tl=l[x],tr=r[x],sl=son[x][0],sr=son[x][1];
l[x]=r[x]=k;
if(k!=tl){
int y=++tot;
l[y]=tl;r[y]=k-1;
setson(y,0,sl);
up(y);
S.change(1,1,R,tl,k-1,y);
setson(x,0,y);
}else setson(x,0,sl);
if(k!=tr){
int y=++tot;
l[y]=k+1;r[y]=tr;
setson(y,1,sr);
up(y);
S.change(1,1,R,k+1,tr,y);
setson(x,1,y);
}else setson(x,1,sr);
up(x);
ans=sum[son[x][0]]+1;
return x;
}
inline void top(int k){//把编号为k的点放在首位
int x=takeout(k),a=son[x][0],b=son[x][1],i;
if(b){
f[b]=0;
i=b;
while(son[i][0])i=son[i][0];
splay(i);
setson(i,0,a);
up(i);
}else root=a;
son[x][0]=0;
setson(x,1,root);
up(root=x);
}
inline void bottom(int k){//把编号为k的点放在末尾
int x=takeout(k),a=son[x][0],b=son[x][1],i;
if(b){
f[b]=0;
i=b;
while(son[i][0])i=son[i][0];
splay(i);
setson(i,0,a);
up(i);
}else root=a;
son[x][1]=0;
setson(x,0,root);
up(root=x);
}
inline void change(int k,int p){//把编号为k的点的编号改为p
int x=takeout(k);
l[x]=r[x]=p;
S.change(1,1,R,p,p,x);
}
int n,m,k,x,y;
int main(){
read(n);read(m);
init(n);
S.init();
while(m--){
read(k);read(x);x-=ans;
if(k==1){
read(y);y-=ans;
change(x,y);
printf("%d\n",ans);
}
if(k==2)top(x),printf("%d\n",ans);
if(k==3)bottom(x),printf("%d\n",ans);
if(k==4)printf("%d\n",ans=kth(x));
}
return 0;
}

  

BZOJ3595 : [Scoi2014]方伯伯的Oj的更多相关文章

  1. [BZOJ3595][SCOI2014]方伯伯的OJ(裂点Splay)

    用一棵Splay按名次维护每个点,其中一个节点对应初始编号连续的一段区间,这样总节点数是$O(m)$的. 对每个编号记录这个点被Splay的那个节点维护,用std::map存储,只记录被修改的点. 每 ...

  2. 2019.03.28 bzoj3595: [Scoi2014]方伯伯的Oj(splay+map+set)

    传送门 题意简述: 给一个有优先级的nnn个人的序列,初始的时候第iii个人排名为iii,现在有mmm个操作,种类如下: 把编号为xxx的改成yyy,输出改前xxx的排名 把编号为xxx放到队首,输出 ...

  3. BZOJ 3595: [Scoi2014]方伯伯的Oj SBT+可持久化Treap

    3595: [Scoi2014]方伯伯的Oj Time Limit: 6 Sec  Memory Limit: 256 MBSubmit: 102  Solved: 54[Submit][Status ...

  4. 洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树

    洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树 题目描述 方伯伯正在做他的 \(Oj\) .现在他在处理 \(Oj\) 上的用户排名问题. \(Oj\) 上注册了 \(n\) 个用户 ...

  5. luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树

    LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...

  6. [SCOI2014]方伯伯的OJ(线段树)

    方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题.Oj上注册了n个用户,编号为1-n“,一开始他们按照编号排名. 方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和编号: 1.操作格式为 ...

  7. [SCOI2014]方伯伯的OJ

    看到这道题的第一想法就是要用FHQ treap 过了这道题...于是至今尚未成功(华丽的 T 掉了 (╯‵□′)╯︵┻━┻ ).于是附个地址. 然后水一波博客. 题意简介 emmmm...方伯伯脑抽做 ...

  8. 洛谷 P3285 / loj 2212 [SCOI2014] 方伯伯的 OJ 题解【平衡树】【线段树】

    平衡树分裂钛好玩辣! 题目描述 方伯伯正在做他的 OJ.现在他在处理 OJ 上的用户排名问题. OJ 上注册了 \(n\) 个用户,编号为 \(1\sim n\),一开始他们按照编号排名.方伯伯会按照 ...

  9. BZOJ 3595: [Scoi2014]方伯伯的Oj Splay + 动态裂点 + 卡常

    Description 方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题. Oj上注册了n个用户,编号为1-”,一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和 ...

随机推荐

  1. compact过滤数组中的nil

    http://ruby-doc.org/core-2.2.0/Array.html#method-i-compact compact → new_aryclick to toggle source R ...

  2. scp 命令

    复制文件: (1)将本地文件拷贝到远程                scp  文件名 用户名@计算机IP或者计算机名称:远程路径        (2)从远程将文件拷回本地               ...

  3. 7 Types of Regression Techniques you should know!

    翻译来自:http://news.csdn.net/article_preview.html?preview=1&reload=1&arcid=2825492 摘要:本文解释了回归分析 ...

  4. Coursera台大机器学习课程笔记13 -- Regularization

    这一节讲的是正则化,在优化中一直会用到正则化项,上课的时候老师一句话代过,没有作过多的解释.听完这节课后, 才明白好大学和野鸡大学的区别有多大.总之,这是很有收获的一节课. 首先介绍了为什么要正则化, ...

  5. java.sql.date与java.util.date区别以及数据库中插入带时分秒的时间

    java.sql.Date,java.sql.Time和java.sql.Timestamp三个都是java.util.Date的子类(包装类). java.sql.Date是java.util.Da ...

  6. [官方教程] [ES4封装教程]2.使用 Easy Sysprep v4 封装 Windows XP

    (一)备份当前操作系统封装的第一步,其实是备份当前安装好的操作系统.避免我们在之后的步骤中出现问题,以至于还要重新安装操作系统,浪费时间精力.系统备份想必大家都会.对于WinXP而言,建议使用Ghos ...

  7. HLG2081分苹果

    苹果 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 39(24 users) Total Accepted: 29(22 users) ...

  8. 推荐一个linux下的web压力测试工具神器webbench

    推荐一个linux下的web压力测试工具神器webbench2014-04-30 09:35:29   来源:   评论:0 点击:880 用多了apache的ab工具之后你就会发现ab存在很多问题, ...

  9. codeforces C. Arithmetic Progression 解题报告

    题目链接:http://codeforces.com/problemset/problem/382/C 题目意思:给定一个序列,问是否可以通过只插入一个数来使得整个序列成为等差数列,求出总共有多少可能 ...

  10. Cocos2d-JS坐标系统

    标准屏幕坐标系 如果接触过iOS,Android,Windows Phone等系统的应用开发,或使用DOM,CSS开发过Web网页,开发者会非常熟悉所谓的标准屏幕坐标系:左上角为原点,向右为X轴正方向 ...