看到这道题的第一想法就是要用FHQ treap 过了这道题...于是至今尚未成功(华丽的 T 掉了 (╯‵□′)╯︵┻━┻ )。于是附个地址。

然后水一波博客。

题意简介

emmmm...方伯伯脑抽做了个 oj ,然后想要在对 oj 上的 1~n 编号的用户乱来(并且还对他的乱来操作进行了加密)。你需要维护一棵平衡树完成方伯伯的一波操作

你的平衡树需要支持这些操作: 1. 修改编号; 2. 把一个人放到树的最左边; 3. 把一个人放到树的最右边;4.输出一个排名对应的编号。

题目分析

然后这道题非常坑,要用 map 记录每个节点对应区间右端点的对应节点编号 (听起来很绕,其实就是: 设某节点对应区间右端点为 R , 该节点编号为 p , 那么我们用的map 的 first key 就是 R ,second key 是 p),然后用找某个编号所在的节点用 lower_bound 就好了(才知道map是可以 lower bound 的,并且是以第一关键字作比较的)。我记得有看到用另一种利用 map 的方法,那好像是 普通 treap (splay应该也能用啊)的,而且节点维护的区间也有点混乱...就是这个

Splay 做法

  1 //by Judge2 #include<iostream>3 #include<cstdio>4 #include<map>5 using namespace std;6 const int M=5e5+111;7 //#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)8 char buf[1<<21],*p1=buf,*p2=buf;9 inline int read(){10     int x=0,f=1; char c=getchar();11     for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; 12 for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; 13 } 14 char sr[1<<21],z[20];int C=-1,Z; 15 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 16 inline void print(int x){ 17 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; 18 while(z[++Z]=x%10+48,x/=10); 19 while(sr[++C]=z[Z],--Z);sr[++C]='\n'; 20 } 21 int n,m,cnt,ans,root; 22 map<int,int> mp; 23 struct Node{ 24 int l,r,siz,fa,ch[2]; 25 }t[M]; 26 inline int newnode(int x,int y){ int u=++cnt; t[u].siz=y-x+1,t[u].l=x,t[u].r=y; return u; } 27 inline void pushup(int x){ t[x].siz=t[t[x].ch[0]].siz+t[t[x].ch[1]].siz+t[x].r-t[x].l+1; } 28 inline void rotate(int x){ 29 int y=t[x].fa,z=t[y].fa,sn=t[y].ch[1]==x; 30 t[x].fa=z; if(z) t[z].ch[t[z].ch[1]==y]=x; 31 t[y].ch[sn]=t[x].ch[!sn],t[t[y].ch[sn]].fa=y; 32 t[y].fa=x,t[x].ch[!sn]=y,pushup(y); 33 } 34 inline void splay(int x,int to){ 35 while(t[x].fa^to){ 36 int y=t[x].fa,z=t[y].fa; 37 if(z!=to) rotate((t[z].ch[0]==y)^(t[y].ch[0]==x)?x:y); 38  rotate(x); 39 } pushup(x); if(!to) root=x; 40 } 41 inline int query(int x){ splay(x,0); return t[x].siz-t[t[x].ch[1]].siz; } 42 inline int get_id(int k){ //查询排名为 k 的人的编号 43 int now=root; 44 while(k){ 45 int sum=t[t[now].ch[0]].siz+t[now].r-t[now].l+1; 46 if(t[t[now].ch[0]].siz<k && k<=sum){ 47 k-=t[t[now].ch[0]].siz; break; 48 } else if(sum<k) k-=sum,now=t[now].ch[1]; 49 else now=t[now].ch[0]; 50 } return t[now].l+k-1; 51 } 52 inline void erase(int x){ //删除节点信息 53 int pre=t[x].ch[0],nxt=t[x].ch[1]; 54 while(t[pre].ch[1]) pre=t[pre].ch[1]; 55 while(t[nxt].ch[0]) nxt=t[nxt].ch[0]; 56 if(!pre && !nxt) return (void)(root=0); 57 if(!pre) splay(nxt,root),t[root=nxt].fa=0; 58 else if(!nxt) splay(pre,root),t[root=pre].fa=0; 59 else splay(pre,0),splay(nxt,pre),t[nxt].ch[0]=0,pushup(nxt),pushup(pre); 60 t[x].ch[0]=t[x].ch[1]=0,t[x].siz=1; //不知道为什么这里不写会 T (懒得想咯应该是编号改完可能会改回来的问题吧) 61 } 62 inline void push_front(int x){ //插头 63 if(!root) return (void)(root=x); int fa=root; 64 while(t[fa].ch[0]) ++t[fa].siz,fa=t[fa].ch[0]; 65 ++t[fa].siz,t[fa].ch[0]=x,t[x].fa=fa,splay(x,0); 66 } 67 inline void push_back(int x){ //插尾 68 if(!root) return (void)(root=x); int fa=root; 69 while(t[fa].ch[1]) ++t[fa].siz,fa=t[fa].ch[1]; 70 ++t[fa].siz,t[fa].ch[1]=x,t[x].fa=fa,splay(x,0); 71 } 72 inline void split(int x,int id){ //拆出节点 73 int L=t[x].l,R=t[x].r,ls,rs; 74 if(L==R) return ; //不用拆 75 if(L==id){ //最左端 76 mp[R]=rs=++cnt,mp[id]=x; 77 t[rs].ch[1]=t[x].ch[1]; 78 t[t[rs].ch[1]].fa=rs; 79 t[x].ch[1]=rs,t[rs].fa=x; 80 t[rs].l=L+1,t[rs].r=R,t[x].r=L; 81  pushup(rs),pushup(x); 82 } else if(R==id){ //最右端 83 mp[R-1]=ls=++cnt,mp[id]=x; 84 t[ls].ch[0]=t[x].ch[0]; 85 t[t[ls].ch[0]].fa=ls; 86 t[x].ch[0]=ls,t[ls].fa=x; 87 t[ls].l=L,t[ls].r=R-1,t[x].l=R; 88  pushup(ls),pushup(x); 89 } else{ //在中间 90 mp[id]=x,mp[id-1]=ls=++cnt,mp[R]=rs=++cnt; 91 t[ls].ch[0]=t[x].ch[0],t[rs].ch[1]=t[x].ch[1]; 92 t[t[ls].ch[0]].fa=ls,t[t[rs].ch[1]].fa=rs; 93 t[x].ch[0]=ls,t[x].ch[1]=rs,t[ls].fa=t[rs].fa=x; 94 t[x].l=t[x].r=id,t[ls].l=L,t[ls].r=id-1,t[rs].l=id+1,t[rs].r=R; 95  pushup(ls),pushup(rs),pushup(x); 96  } 97 } 98 signed main() { 99 n=read(),m=read(), 100 mp[n]=root=newnode(1,n); 101 for(int x,y,pos,opt;m;--m){ 102 opt=read(); 103 switch(opt){ 104 case 1: 105 x=read()-ans,y=read()-ans; 106 pos=mp.lower_bound(x)->second; //map 里面找节点编号 107 split(pos,x),ans=query(pos); //拆出节点查排名 108 t[pos].l=t[pos].r=y,mp[y]=pos; //修改信息输答案 109 print(ans); break; 110 case 2: 111 x=read()-ans, pos=mp.lower_bound(x)->second; 112 split(pos,x),ans=query(pos),erase(pos); //拆除节点再删除 113 push_front(pos),print(ans); break; //节点重新加入树 114 case 3: 115 x=read()-ans, pos=mp.lower_bound(x)->second; 116 split(pos,x),ans=query(pos),erase(pos); 117 push_back(pos),print(ans); break; 118 case 4: 119 x=read()-ans,ans=get_id(x),print(ans); break; //询问编号直输出 120  } 121 } Ot(); return 0; 122 }

FHQ treap

转载于:https://www.cnblogs.com/Judge/p/9538306.html

[SCOI2014]方伯伯的OJ相关推荐

  1. 【bzoj 3595】: [Scoi2014]方伯伯的Oj

    传送门&& 原题解 蒟蒻终于做到一道方伯伯的题了-- 调了一个上午一直TLE(发现自己打了好久的splay板子竟然是错的这种丢人事情我就不说了) 很明显,要建两棵树,$T1$维护排名, ...

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

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

  3. 「SCOI2014」方伯伯的 OJ 解题报告

    「SCOI2014」方伯伯的 OJ 和列队有点像,平衡树点分裂维护即可 但是需要额外用个set之类的对编号查找点的位置 插入完了后记得splay,删除时注意特判好多东西 Code: #include ...

  4. bzoj 3594: [Scoi2014]方伯伯的玉米田

    3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MB Submit: 1399  Solved: 627 [Submit][ ...

  5. [bzoj 3594] [Scoi2014]方伯伯的玉米田

    [bzoj 3594] [Scoi2014]方伯伯的玉米田 Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为 ...

  6. 3597: [Scoi2014]方伯伯运椰子

    3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec   Memory Limit: 64 MB Submit: 388   Solved: 239 [ Submit][ ...

  7. [bzoj3597][SCOI2014]方伯伯运椰子

    3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MB Submit: 353 Solved: 215 [Submit][Statu ...

  8. BZOJ 3597 SCOI2014 方伯伯送椰子 网络流分析+SPFA

    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3597 Description 四川的方伯伯为了致富,决定引进海南的椰子树.方伯伯的椰子园十 ...

  9. bzoj3597: [Scoi2014]方伯伯运椰子【分数规划+费用流】

    Description 四川的方伯伯为了致富,决定引进海南的椰子树. 方伯伯的椰子园十分现代化,椰子园中有一套独特的交通系统. 现在用点来表示交通节点,边来表示道路.这样,方伯伯的椰子园就可以看作一个 ...

最新文章

  1. effective C++ 读书笔记(11-28)
  2. 端口基础常识大全+常用端口对照
  3. mysql中删除标识列的语句_MySQL中一些常用的数据表操作语句笔记
  4. boost::hana::string_c用法的测试程序
  5. oracle布尔true 1,将.NET布尔数据类型映射到实体框架中的oracle数(1,0)会抛出错误
  6. 这个网盘下载60MB/s!PanDownload复活了!
  7. rabbitmq入门-第一讲安装
  8. Matlab图像处理函数:regionprops
  9. 最小配筋率、配筋率、超筋率定义与分析
  10. 拼多多开放平台订单信息查询接口【pdd.order.basic.list.get订单基础信息列表查询接口(根据成交时间)】代码对接教程
  11. 实用ps教程-第一节:使用ps制作GIF动图
  12. 转帖]实现永久保存注册表数据(转自阿冰blog)
  13. CMM(软件能力成熟度模型)
  14. uni-app弹窗多选样式分享
  15. /sdcard目录详解
  16. html如何固定字号,css怎么控制字体大小?
  17. 英语拼读规则28条(必知)
  18. 多智能体强化学习(五)MARL的挑战
  19. VC开发程序创建Dump文件
  20. html聚光灯特效,jquery实现聚光灯效果的方法

热门文章

  1. 融合趋势下基于 Flink Kylin Hudi 湖仓一体的大数据生态体系
  2. 9个典型的开发者关系面试题
  3. 阿里面试官:什么样的人能在阿里晋升?
  4. ajax将数据显示在class为content的标签中_python selenium:自动化爬取某鱼数据
  5. 如何改造UE4用于赛璐璐3D卡渲?这里有一份日本大厂的实操分享
  6. 你以为的并不是你所以为的,《传说之下》Undertale打破游戏的墙
  7. Android游戏开发中绘制游戏触摸轨迹的曲线图
  8. 神经网络训练中,错误数据集对模型结果的影响有多大
  9. ASP.NET Core必备笔试题(含答案)
  10. JAVA字符串数学公式运算-辅助类-支持浮点数错误纠正-低消耗-高可用性-小数点后面保留16位小数