然而我还是在继续刷水题。。。

终于解开了区间第k大的心结。。。

比较裸的线段树套平衡树,比较不好想的是求区间第k大时需要二分一下答案,然后问题就转化为了第一个操作。复杂度nlog3n。跑的比较慢。。。

在查前驱后继的时候写错了。。。如果要直接赋值ans的话前驱是k[x]<=z,后继是k[x]<z,如果都写<的话需要取max和min。。。(不是第一次犯这种错了)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define lc x*2,l,mid
  6. #define rc x*2+1,mid+1,r
  7. #define ls(x) ch[x][0]
  8. #define rs(x) ch[x][1]
  9. #define inf 0x3f3f3f3f
  10. using namespace std;
  11. int n,m;
  12. int root[*];
  13. int size[*],k[*];
  14. int ch[*][],fa[*];
  15. int a[];
  16. int cnt;
  17. inline void push_up(int x)
  18. {
  19. size[x]=size[ch[x][]]+size[ch[x][]]+;
  20. return ;
  21. }
  22. inline void rotate(int p)
  23. {
  24. int q=fa[p],y=fa[q],x=(ch[q][]==p);
  25. ch[q][x]=ch[p][x^];fa[ch[q][x]]=q;
  26. ch[p][x^]=q;fa[q]=p;fa[p]=y;
  27. if(y)
  28. {
  29. if(ls(y)==q)ch[y][]=p;
  30. else ch[y][]=p;
  31. }
  32. push_up(q);push_up(p);
  33. }
  34. inline void splay(int now,int x)
  35. {
  36. for(int y;y=fa[x];rotate(x))
  37. {
  38. if(fa[y])
  39. {
  40. if((ls(y)==x&&ls(fa[y])==y)||(rs(y)==x&&rs(fa[y])==y))rotate(y);
  41. else rotate(x);
  42. }
  43. }
  44. root[now]=x;
  45. }
  46. inline void insert(int now,int x,int z)
  47. {
  48. size[x]++;
  49. while(ch[x][k[x]<z])x=ch[x][k[x]<z],size[x]++;
  50. ch[x][k[x]<z]=++cnt;fa[cnt]=x;size[cnt]=;k[cnt]=z;splay(now,cnt);
  51. }
  52. inline void build(int x,int l,int r)
  53. {
  54. root[x]=++cnt;k[cnt]=a[l];size[cnt]=;
  55. for(int i=l+;i<=r;i++)insert(x,root[x],a[i]);
  56. int mid=(l+r)>>;
  57. if(l<r)build(lc),build(rc);
  58. return ;
  59. }
  60. inline int fd(int x,int z)
  61. {
  62. int ans=;
  63. while(x)
  64. {
  65. if(k[x]>z)
  66. {
  67. x=ch[x][];
  68. }
  69. else ans+=size[ch[x][]]+,x=ch[x][];
  70. }
  71. return ans;
  72. }
  73. inline int qur(int x,int l,int r,int ll,int rr,int kk)
  74. {
  75. if(ll<=l&&rr>=r)
  76. {
  77. return fd(root[x],kk);
  78. }
  79. int mid=(l+r)>>;
  80. int ans=;
  81. if(ll<=mid)ans+=qur(lc,ll,rr,kk);
  82. if(rr>mid)ans+=qur(rc,ll,rr,kk);
  83. return ans;
  84. }
  85. inline int find(int x,int z)
  86. {
  87. if(k[x]==z)return x;
  88. while(ch[x][k[x]<z])
  89. {
  90. x=ch[x][k[x]<z];if(k[x]==z)return x;
  91. }
  92. return ;
  93. }
  94. inline void del(int now,int x)
  95. {
  96. splay(now,x);
  97. if(!ch[x][])root[now]=ch[x][],fa[ch[x][]]=;
  98. else if(!ch[x][])root[now]=ch[x][],fa[ch[x][]]=;
  99. else
  100. {
  101. fa[ch[x][]]=;int tmp=ch[x][];
  102. while(ch[tmp][])tmp=ch[tmp][];
  103. splay(now,tmp);ch[tmp][]=ch[x][];fa[ch[x][]]=tmp;push_up(tmp);
  104. }
  105. }
  106. inline void gai(int x,int l,int r,int pos,int z)
  107. {
  108. insert(x,root[x],z);
  109. int x1=find(root[x],a[pos]);
  110. del(x,x1);
  111. if(l==r)return ;
  112. int mid=(l+r)>>;
  113. if(pos<=mid)gai(lc,pos,z);
  114. else gai(rc,pos,z);
  115. }
  116. inline int pre(int x,int z)
  117. {
  118. int ans=-inf;
  119. while(ch[x][k[x]<=z])
  120. {
  121. if(k[x]<=z)ans=k[x];
  122. x=ch[x][k[x]<=z];
  123. }if(k[x]<=z)ans=max(ans,k[x]);
  124. return ans;
  125. }
  126. inline int suc(int x,int z)
  127. {
  128. int ans=inf;
  129. while(ch[x][k[x]<z])
  130. {
  131. if(k[x]>=z)ans=k[x];
  132. x=ch[x][k[x]<z];
  133. }if(k[x]>=z)ans=min(ans,k[x]);
  134. return ans;
  135. }
  136. inline int qur_pre(int x,int l,int r,int ll,int rr,int kk)
  137. {
  138. if(l>=ll&&r<=rr)
  139. {
  140. return pre(root[x],kk);
  141. }
  142. int ans=-inf;
  143. int mid=(l+r)>>;
  144. if(ll<=mid)ans=max(ans,qur_pre(lc,ll,rr,kk));
  145. if(rr>mid)ans=max(ans,qur_pre(rc,ll,rr,kk));
  146. return ans;
  147. }
  148. inline int qur_suc(int x,int l,int r,int ll,int rr,int kk)
  149. {
  150. if(l>=ll&&r<=rr)
  151. {
  152. return suc(root[x],kk);
  153. }
  154. int ans=inf;
  155. int mid=(l+r)>>;
  156. if(ll<=mid)ans=min(ans,qur_suc(lc,ll,rr,kk));
  157. if(rr>mid)ans=min(ans,qur_suc(rc,ll,rr,kk));
  158. return ans;
  159. }
  160. int mn,mx;
  161. int main()
  162. {
  163. scanf("%d%d",&n,&m);mn=inf;mx=-inf;
  164. for(int i=;i<=n;i++)
  165. {
  166. scanf("%d",&a[i]);mn=min(mn,a[i]);mx=max(mx,a[i]);
  167. }
  168. build(,,n);
  169. for(int i=;i<=m;i++)
  170. {
  171. int t1;
  172. scanf("%d",&t1);
  173. int l,r,kk;
  174. if(t1==)
  175. {
  176. scanf("%d%d%d",&l,&r,&kk);
  177. printf("%d\n",qur(,,n,l,r,kk-)+);
  178. }
  179. else if(t1==)
  180. {
  181. scanf("%d%d%d",&l,&r,&kk);
  182. int ha=mn;int ta=mx;
  183. while(ha<=ta)
  184. {
  185. int mid=(ha+ta)>>;
  186. if(qur(,,n,l,r,mid)<kk)ha=mid+;
  187. else ta=mid-;
  188. }
  189. printf("%d\n",ha);
  190. }
  191. else if(t1==)
  192. {
  193. scanf("%d%d",&l,&kk);
  194. gai(,,n,l,kk);a[l]=kk;
  195. }
  196. else if(t1==)
  197. {
  198. scanf("%d%d%d",&l,&r,&kk);
  199. printf("%d\n",qur_pre(,,n,l,r,kk-));
  200. }
  201. else
  202. {
  203. scanf("%d%d%d",&l,&r,&kk);
  204. printf("%d\n",qur_suc(,,n,l,r,kk+));
  205. }
  206. }
  207. return ;
  208. }

bzoj 3196 树套树模板的更多相关文章

  1. bzoj 1901: Zju2112 Dynamic Rankings(树套树)

    1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...

  2. 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)

    [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...

  3. 洛谷P3380 【模板】二逼平衡树(树套树)(线段树+树状数组)

    P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...

  4. 洛谷 P3380 【模板】二逼平衡树(树套树)-线段树套splay

    P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...

  5. [BZOJ 3489] A simple rmq problem 【可持久化树套树】

    题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...

  6. P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)

    P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...

  7. 【Luogu】P3380树套树模板(线段树套Splay)

    题目链接 幸甚至哉,歌以咏志. 拿下了曾经是那么遥不可及的线段树,学会了曾经高不可攀的平衡树,弄懂了装B的时候才挂在嘴边的树套树. 每道模板都是链上的一颗珠子.把它们挨个串起来,就成为我成长的历程. ...

  8. ZJOI2013 K大数查询 和 LG3380【模板】二逼平衡树(树套树)

    K大数查询 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c:如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的 ...

  9. 「luogu3380」【模板】二逼平衡树(树套树)

    「luogu3380」[模板]二逼平衡树(树套树) 传送门 我写的树套树--线段树套平衡树. 线段树上的每一个节点都是一棵 \(\text{FHQ Treap}\) ,然后我们就可以根据平衡树的基本操 ...

  10. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

随机推荐

  1. JQuery 获取touchstart,touchmove,touchend 坐标

    JQuery写法: $('#id').on('touchstart',function(e) { var _touch = e.originalEvent.targetTouches[0]; var ...

  2. 关于IOS免证书真机安装的过程和问题

    由于本人是边工作边转的IOS,所以一直都没怎么使用过免证书安装过程,通常都是公司申请的99美元的账号直接开发.但是前两天有个朋友需要在展会上用的Ipad上安装内网应用,申请一个苹果账号还要审核前后加起 ...

  3. 从浏览器输入url到页面加载完成都发生了什么

    一个http请求的过程 简要介绍一下一个http请求的网络传输过程: DNS Lookup先获得URL对应的IP地址 Socket Connect浏览器和服务器建立TCP连接 Send Request ...

  4. [转]源代码的管理和发布:以SVN为例

    FROM : http://ju.outofmemory.cn/entry/47277 前几天在微博吐槽了SVN的几个不爽的地方:.svn文件满天飞.分支管理的麻烦.不爽一般来说都是有过对比后才有如此 ...

  5. [win]系统优化工具dism++

    系统优化工具, 确实能将c盘扩大个2-3g. 主要是删除日志 优化系统等功能. https://www.chuyu.me/

  6. [py]shell着色

    print "\033[32;1myou are 30 older and little than 40\033[0m"

  7. struts2: 通过流输出实现exce导出

    参考下面代码,在Action中加一个方法: // 导出excel public String excel() throws Exception { StringBuffer excelBuf = ne ...

  8. React Native 中组件的生命周期

    概述 就像 Android 开发中的 View 一样,React Native(RN) 中的组件也有生命周期(Lifecycle).所谓生命周期,就是一个对象从开始生成到最后消亡所经历的状态,理解生命 ...

  9. swift 初探NSURLSession

    进行封装, 新建一个类.network class Network1: NSObject { // 没有参数+结果的get  自定义 HTTP method 和 URL+闭包 static func ...

  10. Java 基础【08】.class getClass () forName() 详解

    类名.class是Class对象的句柄,每个被加载的类,在jvm中都会有一个Class对象与之相对应. 如果要创建新的对象,直接使用Class对象的局部class.forName就可以了,不需要用ne ...