Dynamic Rankings

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112

Description

The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.

Your task is to write a program for this computer, which

- Reads N numbers from the input (1 <= N <= 50,000)

- Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change some a[i] to t.

Input

The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.

The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format

Q i j k or
C i t

It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.

There're NO breakline between two continuous test cases.

Output

For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],..., a[j])

There're NO breakline between two continuous test cases.

Sample Input

2
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

Sample Output

3
6
3
6

HINT

题意

动态第k大

1. Q x y k,查询区间[x,y]第k大的数是啥

2. C x y,把第x个数变成y

题解:

树套树

在每一个区间里面,我们都套入一个Treap/Splay就好了

1操作很简单,暴力进行二分就好了,我们在[L,R]区间所在的Treap里面查询Rank

2操作,在所有这个数所在的区间,我们都删除原来的,再加入新的就好了

代码:

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<ctime>
  6. using namespace std;
  7.  
  8. #define maxn 1000001
  9. int tmp = ;
  10. ////////////////treap
  11. struct Treap
  12. {
  13. int root[maxn],sz,s[maxn],ls[maxn],rs[maxn],v[maxn],w[maxn],rnd[maxn];
  14. void init()
  15. {
  16. memset(root,,sizeof(root));
  17. sz=;
  18. }
  19. void Updata(int k)
  20. {
  21. s[k]=s[ls[k]]+s[rs[k]]+w[k];
  22. }
  23. void Rturn(int &k)
  24. {
  25. int t;
  26. t=ls[k],ls[k]=rs[t],rs[t]=k,s[t]=s[k];
  27. Updata(k);k=t;
  28. }
  29. void Lturn(int &k)
  30. {
  31. int t;
  32. t=rs[k],rs[k]=ls[t],ls[t]=k,s[t]=s[k];
  33. Updata(k);k=t;
  34. }
  35. void Insert(int &k,int num)
  36. {
  37. if(!k)
  38. {
  39. k=++sz;s[k]=w[k]=;ls[k]=rs[k]=;rnd[k]=rand();
  40. v[k]=num;return;
  41. }
  42. s[k]++;
  43. if(v[k]==num)w[k]++;
  44. else if(num<v[k])
  45. {
  46. Insert(ls[k],num);
  47. if(rnd[ls[k]]<rnd[k])
  48. Rturn(k);
  49. }
  50. else
  51. {
  52. Insert(rs[k],num);
  53. if(rnd[rs[k]]<rnd[k])
  54. Lturn(k);
  55. }
  56. }
  57. void Del(int &k,int num)
  58. {
  59. if(v[k]==num)
  60. {
  61. if(w[k]>){
  62. w[k]--;
  63. s[k]--;
  64. return;
  65. }
  66. if(ls[k]*rs[k]==)
  67. k=ls[k]+rs[k];
  68. else if(rnd[ls[k]]<rnd[rs[k]])
  69. Rturn(k),Del(k,num);
  70. else
  71. Lturn(k),Del(k,num);
  72. }
  73. else if(num<v[k]){
  74. Del(ls[k],num);
  75. s[k]--;
  76. }
  77. else{
  78. Del(rs[k],num);
  79. s[k]--;
  80. }
  81. }
  82. void Find(int k,int num)
  83. {
  84. if(!k)return;
  85. if(v[k]<=num){
  86. tmp+=s[ls[k]]+w[k];
  87. Find(rs[k],num);
  88. }
  89. else Find(ls[k],num);
  90. }
  91. }Tr;
  92.  
  93. /////////////////////
  94.  
  95. /////////////////////线段树
  96.  
  97. void Seg_insert(int k,int l,int r,int x,int num)
  98. {
  99. Tr.Insert(Tr.root[k],num);
  100. if(l==r)return;
  101. int mid=(l+r)/;
  102. if(x<=mid)Seg_insert(k*,l,mid,x,num);
  103. else Seg_insert(k*+,mid+,r,x,num);
  104. }
  105.  
  106. void Seg_change(int k,int l,int r,int x,int Now,int Pre)
  107. {
  108. Tr.Del(Tr.root[k],Pre);
  109. Tr.Insert(Tr.root[k],Now);
  110. if(l==r)return;
  111. int mid=(l+r)/;
  112. if(x<=mid)Seg_change(k*,l,mid,x,Now,Pre);
  113. else Seg_change(k*+,mid+,r,x,Now,Pre);
  114. }
  115. void Seg_query(int k,int l,int r,int L,int R,int num)
  116. {
  117. if(l==L&&r==R)
  118. {
  119. Tr.Find(Tr.root[k],num);
  120. return;
  121. }
  122. int mid = (l+r)/;
  123. if(mid>=R)
  124. Seg_query(k*,l,mid,L,R,num);
  125. else if(mid<L)
  126. Seg_query(k*+,mid+,r,L,R,num);
  127. else{
  128. Seg_query(k*,l,mid,L,mid,num);
  129. Seg_query(k*+,mid+,r,mid+,R,num);
  130. }
  131. }
  132. ///////////////////////////
  133. int a[maxn];
  134. int main()
  135. {
  136. srand(time(NULL));
  137. int t;scanf("%d",&t);
  138. while(t--)
  139. {
  140. Tr.init();
  141. int n,m;scanf("%d%d",&n,&m);
  142. for(int i=;i<=n;i++)
  143. {
  144. scanf("%d",&a[i]);
  145. Seg_insert(,,n,i,a[i]);
  146. }
  147. char op[];
  148. for(int i=;i<=m;i++)
  149. {
  150. scanf("%s",op);
  151. if(op[]=='C')
  152. {
  153. int x,y;scanf("%d%d",&x,&y);
  154. Seg_change(,,n,x,y,a[x]);
  155. a[x]=y;
  156. }
  157. else
  158. {
  159. int x,y,z;scanf("%d%d%d",&x,&y,&z);
  160. int l = ,r = 1e9;
  161. while(l<=r)
  162. {
  163. int mid = (l+r)/;
  164. tmp = ;Seg_query(,,n,x,y,mid);
  165. if(tmp>=z)r=mid-;
  166. else l=mid+;
  167. }
  168. printf("%d\n",l);
  169. }
  170. }
  171. }
  172. }

zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap的更多相关文章

  1. ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)

    题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...

  2. 整体二分&cdq分治 ZOJ 2112 Dynamic Rankings

    题目:单点更新查询区间第k大 按照主席树的思想,要主席树套树状数组.即按照每个节点建立主席树,然后利用树状数组的方法来更新维护前缀和.然而,这样的做法在实际中并不能AC,原因即卡空间. 因此我们采用一 ...

  3. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  4. 整体二分(SP3946 K-th Number ZOJ 2112 Dynamic Rankings)

    SP3946 K-th Number (/2和>>1不一样!!) #include <algorithm> #include <bitset> #include & ...

  5. ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  6. ZOJ 2112 Dynamic Rankings(主席树の动态kth)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 The Company Dynamic Rankings ...

  7. ZOJ - 2112 Dynamic Rankings(BIT套主席树)

    纠结了好久的一道题,以前是用线段树套平衡树二分做的,感觉时间复杂度和分块差不多了... 终于用BIT套函数式线段树了过了,120ms就是快,此题主要是卡内存. 假设离散后有ns个不同的值,递归层数是l ...

  8. BZOJ 1901 洛谷 P2617 ZOJ 2112 Dynamic Rankings

    以下时空限制来自zoj Time limit 10000 ms Memory limit 32768 kB OS Linux Source Online Contest of Christopher' ...

  9. zoj 2112 Dynamic Rankings(主席树&amp;动态第k大)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

随机推荐

  1. 构造函数后面的base()

    先执行父类的对应的构造函数,再执行当前的构造函数. 关于子类对象的构造函数和父类构造函数的执行顺序 以下内容转自:http://blog.csdn.net/todototry/article/deta ...

  2. 9月5日 华为2014校园招聘的机试题目_C语言版答案

    手有些生了. 题目: 通过键盘输入一串小写字母(a~z)组成的字符串.请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串.压缩规则:1.仅压缩连续重复出现的字符.比如 ...

  3. bjfu1097 图标排列

    这是2011年百度之星的一道题.这题的做法就是找规律,规律找对了,代码极水.规律我一开始也没有找到,后来经人提醒,发现如下规律:对于每个开发者,其所有应用的分离度和一定是其第一个应用与最后一个应用的距 ...

  4. virtualbox虚拟机中mysql远程连接登陆报2003错误的解决方法

    最近在virtualbox中安装了Ubuntu 14,配置了一个mysql server,设置的桥接网络模式.在其他电脑连接的时候,总是报2003错误.开始以为是localhost没有置换为%,运行u ...

  5. C++实现网格水印之调试笔记(一)

    首先说一下我的一些简单的调试方法,除了常规的断点调试之外,我还会使用注释的方法来调试.当整个工程代码量相当多且调用层次关系较为复杂时,这种方法能够比较高效的定位到出错误的代码段或某个函数,然后在出现错 ...

  6. WebStorm2016.1 破解 激活

    WebStorm2016.1 破解 激活   方法来自 Rover12421 大神. 1.从官网下载WebStorm2016.1安装. 2.下载 破解补丁 并解压,记住路径 3.编辑WebStorm安 ...

  7. 初识HTML 5:关于它的三个三

    来源:http://www.ido321.com/949.html 一.HTML 5受欢迎的三个理由 1.IE.Google.Firefox.Safari.Opera等主流浏览器的支持 1.1  微软 ...

  8. 浅谈JavaScript中的原型模式

    在JavaScript中创建对象由很多种方式,如工厂模式.构造函数模式.原型模式等: <pre name="code" class="html">/ ...

  9. codeforce 702C Cellular Network 二分答案

    http://codeforces.com/contest/702 题意:n个村庄,m个机站,问机站最短半径覆盖完所有村庄 思路:直接二分答案 二分太弱,调了半天..... // #pragma co ...

  10. C++11 之 " = delete "

    1  缺省函数 设计一个类,没有成员函数 (member function),只有成员数据 (member data) class DataOnly { private: std::string st ...