用一棵Splay按名次维护每个点,其中一个节点对应初始编号连续的一段区间,这样总节点数是$O(m)$的。

对每个编号记录这个点被Splay的那个节点维护,用std::map存储,只记录被修改的点。

每次删除时将一个点分裂成[l,k-1],k,[k+1,r]三个点(特判k=l或k=r),再删除k。

注意各种细节。

  1. #include<map>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #define rep(i,l,r) for (int i=(l); i<=(r); i++)
  5. using namespace std;
  6.  
  7. const int N=;
  8. int n,m,rt,nd,ans,op,x,y,L[N],R[N],len[N],f[N],ch[N][];
  9. map<int,int>mp;
  10.  
  11. int get(int l,int r){ nd++; L[nd]=l; R[nd]=r; len[nd]=r-l+; return nd; }
  12. void upd(int x){ len[x]=len[ch[x][]]+len[ch[x][]]+R[x]-L[x]+; }
  13.  
  14. void rot(int &rt,int x){
  15. int y=f[x],z=f[y],w=ch[y][]==x;
  16. if (rt==y) rt=x; else ch[z][ch[z][]==y]=x;
  17. f[x]=z; f[y]=x; f[ch[x][w^]]=y;
  18. ch[y][w]=ch[x][w^]; ch[x][w^]=y; upd(y);
  19. }
  20.  
  21. void splay(int &rt,int x){
  22. while (x!=rt){
  23. int y=f[x],z=f[y];
  24. if (y!=rt) ((ch[z][]==y)^(ch[y][]==x)) ? rot(rt,x) : rot(rt,y);
  25. rot(rt,x);
  26. }
  27. upd(x);
  28. }
  29.  
  30. int split(int x,int k){
  31. int y=get(k+,R[x]); R[x]=k;
  32. if (!ch[x][]) ch[x][]=y,f[y]=x;
  33. else{
  34. int s=ch[x][];
  35. while (ch[s][]) s=ch[s][];
  36. ch[s][]=y; f[y]=s;
  37. }
  38. splay(rt,y); mp[R[x]]=x; mp[R[y]]=y; return y;
  39. }
  40.  
  41. void Split(int &x,int k){
  42. if (k<R[x]) split(x,k);
  43. if (k>L[x]) x=split(x,k-);
  44. splay(rt,x);
  45. }
  46.  
  47. void ins1(int x){
  48. int s=rt;
  49. while (ch[s][]) s=ch[s][];
  50. ch[s][]=x; f[x]=s; splay(rt,x);
  51. }
  52.  
  53. void ins2(int x){
  54. int s=rt;
  55. while (ch[s][]) s=ch[s][];
  56. ch[s][]=x; f[x]=s; splay(rt,x);
  57. }
  58.  
  59. void del(int x){
  60. splay(rt,x);
  61. int ls=ch[x][],rs=ch[x][];
  62. f[ls]=f[rs]=; ch[x][]=ch[x][]=;
  63. if (!ls || !rs) { rt=ls+rs; return; }
  64. int s=ls; while (ch[s][]) s=ch[s][];
  65. splay(ls,s); ch[s][]=rs; f[rs]=rt=s; upd(s);
  66. }
  67.  
  68. int find(int k){
  69. for (int x=rt; ; ){
  70. if (k<=len[ch[x][]]) x=ch[x][];
  71. else{
  72. k-=len[ch[x][]];
  73. if (k<=R[x]-L[x]+) return k+L[x]-;
  74. else k-=R[x]-L[x]+,x=ch[x][];
  75. }
  76. }
  77. }
  78.  
  79. int main(){
  80. freopen("bzoj3595.in","r",stdin);
  81. freopen("bzoj3595.out","w",stdout);
  82. scanf("%d%d",&n,&m); rt=get(,n); mp[n]=;
  83. rep(i,,m){
  84. scanf("%d%d",&op,&x); x-=ans;
  85. if (op==){
  86. scanf("%d",&y); y-=ans;
  87. int t=mp.lower_bound(x)->second;
  88. Split(t,x); printf("%d\n",ans=len[t]-len[ch[t][]]);
  89. L[t]=R[t]=y; mp[y]=t;
  90. }
  91. if (op==){
  92. int t=mp.lower_bound(x)->second;
  93. Split(t,x); printf("%d\n",ans=len[t]-len[ch[t][]]);
  94. del(t); ins1(t);
  95. }
  96. if (op==){
  97. int t=mp.lower_bound(x)->second;
  98. Split(t,x); printf("%d\n",ans=len[t]-len[ch[t][]]);
  99. del(t); ins2(t);
  100. }
  101. if (op==) printf("%d\n",ans=find(x));
  102. }
  103. return ;
  104. }

[BZOJ3595][SCOI2014]方伯伯的OJ(裂点Splay)的更多相关文章

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

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

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

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

  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. BZOJ 3595: [Scoi2014]方伯伯的Oj Splay + 动态裂点 + 卡常

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

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

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

  8. [SCOI2014]方伯伯的OJ

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

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

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

随机推荐

  1. 创造101:如果软件测试工程师组团出道,怎样才能站C位?!

    作者 C位出道的华华 虽然华华是一个软件测试技术宅,可以连续七七四十九天加班不重样,心里除了上班工作学习写代码就没有别的爱好了,但是各种潮流资讯啊狗血剧啊娱乐综艺啊,从来没有错过. 比如说现在大火的& ...

  2. JS设计模式——10.门面模式

    门面模式 这是一种组织性的模式,它可以用来修改类和对象的接口,使其更便于使用.它可以让程序员过得更轻松,使他们的代码变得更容易管理. 门面模式有两个作用: 简化类的接口 消除与使用她的客户代码之间的耦 ...

  3. Gh0st配置加密与解密算法(异或、Base64)

    1.前言 分析木马程序常常遇到很多配置信息被加密的情况,虽然现在都不直接分析而是通过Wireshark之类的直接读记录. 2017年Gh0st样本大量新增,通过对木马源码的分析还发现有利用Gh0st加 ...

  4. Mysql 监控性能状态 QPS/TPS【转】

    QPS(Query per second) 每秒查询量 TPS(Transaction per second)每秒事务量 这是Mysql的两个重要性能指标,需要经常查看,和Mysql基准测试的结果对比 ...

  5. maven profile 优先级

    maven profile是有优先级别 也就是说在setting.xml的profile优先级比pom中同名的profile高. 可以使用 mvn help:active-profiles 这个命令是 ...

  6. 使用免安装压缩包安装MySQL

    OS:Windows 10家庭中文版 MySQL:mysql-5.7.20-winx64.zip 作者:Ben.Z 参考链接: Installing MySQL on Microsoft Window ...

  7. SQLAlchemy-对象关系教程ORM-create

    ORM是建立在SQL语言构造器之上的工具集,用于将Python对象映射到数据库的行,提供了一系列接口用于从数据库中存取对象(行).在ORM 工作时,在底层调用SQL语言构造器的API,这些通用的操作有 ...

  8. 数据库-mysql数据连接

    一:Mysql 连接的使用 在前几章节中,我们已经学会了如果在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据. 本章节我们将向大家介绍如何使用 MySQL 的 JO ...

  9. NLP里面好的学习资料

    别人推荐的网址: http://ruder.io/deep-learning-nlp-best-practices/index.html#wordembeddings

  10. mysql自增id归0

    mysql自增id归0 ALTER TABLE table_name AUTO_INCREMENT=1;