[Scoi2014]方伯伯的OJ(动态开点splay)
开始没看数据范围差点以为是这题了: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)的更多相关文章
- 洛谷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 ...
- luogu P3285 [SCOI2014]方伯伯的OJ splay 线段树
LINK:方伯伯的OJ 一道稍有质量的线段树题目.不写LCT splay这辈子是不会单独写的 真的! 喜闻乐见的是 题目迷惑选手 \(op==1\) 查改用户在序列中的位置 题目压根没说位置啊 只有排 ...
- BZOJ 3595: [Scoi2014]方伯伯的Oj Splay + 动态裂点 + 卡常
Description 方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题. Oj上注册了n个用户,编号为1-”,一开始他们按照编号排名.方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和 ...
- [SCOI2014]方伯伯的OJ(线段树)
方伯伯正在做他的Oj.现在他在处理Oj上的用户排名问题.Oj上注册了n个用户,编号为1-n“,一开始他们按照编号排名. 方伯伯会按照心情对这些用户做以下四种操作,修改用户的排名和编号: 1.操作格式为 ...
- [SCOI2014]方伯伯的OJ
看到这道题的第一想法就是要用FHQ treap 过了这道题...于是至今尚未成功(华丽的 T 掉了 (╯‵□′)╯︵┻━┻ ).于是附个地址. 然后水一波博客. 题意简介 emmmm...方伯伯脑抽做 ...
- 洛谷 P3285 / loj 2212 [SCOI2014] 方伯伯的 OJ 题解【平衡树】【线段树】
平衡树分裂钛好玩辣! 题目描述 方伯伯正在做他的 OJ.现在他在处理 OJ 上的用户排名问题. OJ 上注册了 \(n\) 个用户,编号为 \(1\sim n\),一开始他们按照编号排名.方伯伯会按照 ...
- BZOJ3595 : [Scoi2014]方伯伯的Oj
由于n很大,有2e8,所以不能直接用splay来维护排名 把splay修改一下 每个节点维护一个区间[l,r],表示编号在[l,r]之间的所有点都在这里 需要支持一个takeout操作: 把编号为k的 ...
- 洛谷 P3285 [SCOI2014]方伯伯的OJ
看到这题,第一眼:平衡树水题,随便做一做好了 然后....我在花了n个小时去调试(维护平衡树父节点)之后,... 调了三个小时后,第一次失败的代码(只能查找排名为k的用户编号,不能根据编号查排名) # ...
随机推荐
- 2016蓝桥杯决赛C/C++A组第四题 路径之谜
题意: 小明冒充X星球的骑士,进入了一个奇怪的城堡.城堡里边什么都没有,只有方形石头铺成的地面. 假设城堡地面是 n x n 个方格.[如图1.png]所示. 按习俗,骑士要从西北角走到东南角.可以横 ...
- SFINAE 与 type_traits
SFINAE 与 type_traits SFINAE 替换失败不是错误 (Substitution Failure Is Not An Error),此特性被用于模板元编程. 在函数模板的重载决议中 ...
- Spring(5) -(14) pointcut 语法
AOP的规范本应该由SUM公司提出,但是被AOP联盟捷足先登.AOP联盟指定AOP规范,首先就要解决一个问题,怎么表示切入点,也就是在哪些方法上增强(where) AspectJ 是一个面向切面的框架 ...
- java题求代码,4、现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: int newArr[]={1,3,4,5,6,6,5,4,7,6,7,5}
public class TEST { public static void main(String[] args) { int [] oldArr= {1,3,4,5,0,0,6,6,0,5,4,7 ...
- javascript面向对象编程的3种常见封装形式解析
javascript如何才能脱离函数式编程,拥抱面向对象编程呢,常见的有3种形式,其它形式可以说都是这3种的变种. 1.直接定义对象直接量的形式 var Util={ getType: ...
- git使用散记
1.从远程clone一个项目 git clone ‘项目地址’ //clone项目地 git checkout -b dev origin/dev //远程已有dev分支,新建本地dev分支与远程相对 ...
- part6 城市页面搜索内容开发
keyword 监听时间做一个节流处理 keyword为input输入的内容 //当逻辑卡壳的时候 可以试着重启服务器,浏览器 当搜索内容出现很多的时候 内容无法滚动 可以引入 better-scro ...
- JAVA中汉字的Compare排序
当调用String.compare方法的时候,比较的是Unicode码,并不能对汉字进行准确的排序,所以汉字比较时会出现比较混乱的结果. java.text.Collator类中有一个getInsta ...
- 《C Primer Plus》- 第二章 C语言概述
本笔记写于2020年1月27日. 本系列文章参考的是<C Primer Plus>(第六版),其中里面会有笔者自己的相关补充. 以下示例均运行于macOS Catalina 10.15.2 ...
- Vue-router(5)之 路由的before家族
beforeEach方法 import Vue from 'vue' import Router from 'vue-router' import Son1 from '@/view/New/son1 ...