开始没看数据范围差点以为是这题了:https://www.cnblogs.com/hfctf0210/p/10911340.html

然后看到n<=1e8,怎么这么大?

所以这题需要用动态开点线段树或者动态开点splay,而我上面的那题写的树状数组,为了熟悉splay就用动态开点splay吧而且也不知道这题动态开点线段树怎么写。正常要开两棵splay,但是关于用户的一棵操作简单没有必要开,所以可以用map代替,为了方便lower_bound查询,map记录右端点。然后先要执行三个基本操作:1、查询第k大。2、查询k节点的rank。3、分裂节点,分裂就是直接开新节点即可。然后重点在于2,3操作,一种简便的方法就是将目标节点拆开并旋转到根,将左右子树合并,使其成为第一/倒一。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+;
struct node{int ch[],sz,l,r,fa;}t[N<<];
int n,m,root,cnt,ans;
map<int,int>mp;
int newnode(int l,int r)
{
int k=++cnt;
t[k].ch[]=t[k].ch[]=;
t[k].l=l,t[k].r=r;
t[k].sz=t[k].r-t[k].l+;
return k;
}
void pushup(int k){t[k].sz=t[t[k].ch[]].sz+t[t[k].ch[]].sz+t[k].r-t[k].l+;}
int dir(int k){return t[t[k].fa].ch[]==k;}
void rotate(int x)
{
int y=t[x].fa,z=t[y].fa,d1=dir(x),d2=dir(y);
t[y].ch[d1]=t[x].ch[d1^];
t[t[x].ch[d1^]].fa=y;
t[z].ch[d2]=x;
t[x].fa=z;
t[y].fa=x;
t[x].ch[d1^]=y;
pushup(y),pushup(x);
}
void splay(int x,int goal)
{
while(t[x].fa!=goal)
{
int y=t[x].fa,z=t[y].fa,d1=dir(x),d2=dir(y);
if(z!=goal){if(d1==d2)rotate(y);else rotate(x);}
rotate(x);
}
if(!goal)root=x;
}
int getkth(int rk)
{
int k=root;
while()
{
int son=t[k].ch[];
if(rk<=t[t[k].ch[]].sz)k=t[k].ch[];
else if(rk>t[t[k].ch[]].sz+t[k].r-t[k].l+)
rk-=t[t[k].ch[]].sz+t[k].r-t[k].l+,k=t[k].ch[];
else return t[k].l+rk-t[t[k].ch[]].sz-;
}
}
int getrk(int k){splay(k,);return t[t[k].ch[]].sz+;}
void split(int k,int id)
{
if(t[k].l==t[k].r)return;
int l=,r=;
mp[id]=k;
if(t[k].l!=id)
{
mp[id-]=l=newnode(t[k].l,id-);
t[l].ch[]=t[k].ch[];
t[t[l].ch[]].fa=l;
t[k].ch[]=l;
t[l].fa=k;
}
if(t[k].r!=id)
{
mp[t[k].r]=r=newnode(id+,t[k].r);
t[r].ch[]=t[k].ch[];
t[t[r].ch[]].fa=r;
t[k].ch[]=r;
t[r].fa=k;
}
t[k].l=t[k].r=id;
if(l)pushup(l);
if(r)pushup(r);
pushup(k);
}
void change(int k,int tp)
{
splay(k,);
k=root;
if(!t[k].ch[tp])return;
if(!t[k].ch[tp^])t[k].ch[tp^]=t[k].ch[tp],t[k].ch[tp]=;
else{
k=t[k].ch[tp^];
while(t[k].ch[tp])k=t[k].ch[tp];
t[t[root].ch[tp]].fa=k;
t[k].ch[tp]=t[root].ch[tp];
t[root].ch[tp]=;
splay(t[k].ch[tp],);
}
}
int main()
{
scanf("%d%d",&n,&m);
root=mp[n]=newnode(,n);
while(m--)
{
int op,x,y,pos;scanf("%d%d",&op,&x),x-=ans;
if(op==)
{
scanf("%d",&y),y-=ans;
pos=(*mp.lower_bound(x)).second;
split(pos,x);
printf("%d\n",ans=getrk(pos));
t[pos].l=t[pos].r=y;
mp[y]=pos;
}
else if(op==)printf("%d\n",ans=getkth(x));
else{
int pos=(*mp.lower_bound(x)).second;
split(pos,x);
printf("%d\n",ans=getrk(pos));
change(pos,op-);
}
}
}

[Scoi2014]方伯伯的OJ(动态开点splay)的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. [SCOI2014]方伯伯的OJ

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

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

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

  8. BZOJ3595 : [Scoi2014]方伯伯的Oj

    由于n很大,有2e8,所以不能直接用splay来维护排名 把splay修改一下 每个节点维护一个区间[l,r],表示编号在[l,r]之间的所有点都在这里 需要支持一个takeout操作: 把编号为k的 ...

  9. 洛谷 P3285 [SCOI2014]方伯伯的OJ

    看到这题,第一眼:平衡树水题,随便做一做好了 然后....我在花了n个小时去调试(维护平衡树父节点)之后,... 调了三个小时后,第一次失败的代码(只能查找排名为k的用户编号,不能根据编号查排名) # ...

随机推荐

  1. ES6中字符串的新增方法梳理

    1.String.fromCodePoint(); String,fromCodePoint()方法可以认为是对String.fromCharCode()方法的扩展,这两个方法的共同点在于都是用于Un ...

  2. javascript 解决provisional headers are shown的过程

    请求没有被发送,因为是载入缓存资源. 大概是说 完全相同的请求间隔数毫秒(太短),导致加载失败,查看了chrome控制台发现 Provisional headers are shown 出现在 载入缓 ...

  3. java课程之团队开发冲刺阶段2.6

    总结昨天进度: 1.总体的思路已经完成,代码也差不多了,只剩下对闹钟activity的设置 遇到的困难: 1.在设置震动的时候,对方法有点不太理解,所以使用的时候产生了错误,没有达到预期的效果 今天的 ...

  4. 【转】modelBuilder.Configurations.AddFromAssembly in EF Core

    EntityFramework 6.x protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnMode ...

  5. https://www.jianshu.com/p/fc78dab5736f

    在学习Swift 3的过程中整理了一些笔记,如果想看其他相关文章可前往<Swift 3必看>系列目录 swift 3中对C层级的GCD的API进行了彻头彻尾的改变.本文将从实际使用场景来了 ...

  6. C# 基本元素

    一.构成C#的基本元素 注释和空白编译器不会编译,自动忽略:而标记是可以通过编译器编译的. 关键字 (keyword) 官方定义:关键字是类似标识符的保留的字符序列,不能用作标识符(以 @ 字符开头时 ...

  7. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring自动装配Bean

    除了使用 XML 和 Annotation 的方式装配 Bean 以外,还有一种常用的装配方式——自动装配.自动装配就是指 Spring 容器可以自动装配(autowire)相互协作的 Bean 之间 ...

  8. 寒假day19

    今天编写了人才动态模块,同时刷了一些算法题.

  9. 模块化CommonJs规范 part1

    CommonJS规范 来自<JavaScript 标准参考教程(alpha)>,by 阮一峰 1.概述 Node 应用由模块组成,采用 CommonJS 模块规范. 每个文件就是一个模块, ...

  10. 读书笔记 - js高级程序设计 - 第五章 引用类型

      引用类型 和 类 不是一个概念 用typeof来检测属性是否存在 typeof args.name == "string"  需要实验 访问属性的方法 .号和[] 一般情况下要 ...