纠结了好久的一道题,以前是用线段树套平衡树二分做的,感觉时间复杂度和分块差不多了。。。

终于用BIT套函数式线段树了过了,120ms就是快,此题主要是卡内存。

假设离散后有ns个不同的值,递归层数是log2(ns)左右,nlog(ns),主席树是前缀区间,BIT保存修改的值是mlog2(ns)log2(ns)。

虽然这个算出来还是会爆,但是实际上会有一些结点复用,具体设置多少请相信玄学。(2e6左右)

ZOJ的Node*计算内存似乎有问题,必须用int

  1. /*********************************************************
  2. * ------------------ *
  3. * author AbyssFish *
  4. **********************************************************/
  5. #include<cstdio>
  6. #include<iostream>
  7. #include<cstring>
  8. #include<vector>
  9. #include<algorithm>
  10. #include<cmath>
  11. using namespace std;
  12. //#pragma pack(4)
  13.  
  14. const int MAX_N = 5e4+;
  15. const int MAX_M = 1e4+;
  16. const int MAX_NM = MAX_N+MAX_M;
  17. const int MAX_D = ;
  18. const int MAX_ND = 0xac*MAX_M+0x42fed;//MAX_D*MAX_N+MAX_M*MAX_D*MAX_D;
  19.  
  20. int b[MAX_NM];
  21. int mp_a[MAX_NM];
  22.  
  23. int ns, n_;
  24.  
  25. int N, M;
  26.  
  27. struct Cmd
  28. {
  29. int i, j, k;
  30. }qus[MAX_M];
  31.  
  32. struct Node
  33. {
  34. int lc, rc;
  35. int s;
  36. }p[MAX_ND];
  37.  
  38. int root[MAX_N];
  39. int cnt;
  40.  
  41. #define lsn p[o].lc,l,md
  42. #define rsn p[o].rc,md+1,r
  43.  
  44. void build(int x,int &o,int l = , int r = ns)
  45. {
  46. p[++cnt] = p[o];
  47. o = cnt;
  48. p[o].s++;
  49. if(r > l){
  50. int md = (l+r)>>;
  51. if(x <= md) build(x,lsn);
  52. else build(x,rsn);
  53. }
  54. }
  55.  
  56. int BIT[MAX_N];
  57.  
  58. void inst(int x, int d, int &o, int l = , int r = ns)
  59. {
  60. if(o == ){
  61. p[++cnt] = p[o];
  62. o = cnt;
  63. }
  64. p[o].s += d;
  65. if(l < r){
  66. int md = (l+r)>>;
  67. if(x<=md) inst(x,d,lsn);
  68. else inst(x,d,rsn);
  69. }
  70.  
  71. }
  72.  
  73. #define lowbit(x) ((x)&(-x))
  74.  
  75. void modify_bit(int pos, int x, int d)
  76. {
  77. while(pos <= N){
  78. inst(x,d,BIT[pos]);
  79. pos += lowbit(pos);
  80. }
  81. }
  82.  
  83. typedef vector<int> Prefix;
  84.  
  85. void prefix_bit(int pos, Prefix &res)
  86. {
  87. res.clear();
  88. while(pos > ){
  89. res.push_back(BIT[pos]);
  90. pos -= lowbit(pos);
  91. }
  92. }
  93.  
  94. inline int cal_lft(Prefix &pfx)
  95. {
  96. int re = ;
  97. for(int i = pfx.size()-; i >= ; i--){
  98. re += p[p[pfx[i]].lc].s;
  99. }
  100. return re;
  101. }
  102.  
  103. #define dump(pfx,ch)\
  104. for(i = pfx.size()-; i >= ; i--){\
  105. pfx[i] = p[pfx[i]].ch;\
  106. }
  107.  
  108. Prefix X, Y;
  109.  
  110. int qkth(int k,int l = , int r = ns)
  111. {
  112. if(l == r) return mp_a[l];
  113. else {
  114. int l_cnt = cal_lft(Y)-cal_lft(X);
  115. int md = (l+r)>>, i;
  116. if(k <= l_cnt){
  117. dump(X,lc)
  118. dump(Y,lc)
  119. return qkth(k,l,md);
  120. }
  121. else {
  122. dump(X,rc)
  123. dump(Y,rc)
  124. return qkth(k-l_cnt,md+,r);
  125. }
  126. }
  127.  
  128. }
  129.  
  130. void solve()
  131. {
  132. cnt = ;
  133. memset(BIT+,,sizeof(int)*N);
  134. int i;
  135. for(i = ; i <= N; i++){
  136. root[i] = root[i-];
  137. build(b[i], root[i]);
  138. }
  139.  
  140. for(i = ; i < M; i++){
  141. if(qus[i].j < ){
  142. int pos = qus[i].i;
  143. modify_bit(pos,b[pos],-);
  144. modify_bit(pos,b[pos] = b[qus[i].k],);
  145. }
  146. else {
  147. int L = qus[i].i-, R = qus[i].j;
  148. prefix_bit(L,X);
  149. prefix_bit(R,Y);
  150. X.push_back(root[L]);
  151. Y.push_back(root[R]);
  152. printf("%d\n",qkth(qus[i].k));
  153. }
  154. }
  155. }
  156.  
  157. int * const a = (int *)(p+);
  158. int * const r = a + MAX_NM;
  159.  
  160. void init()
  161. {
  162. scanf("%d%d",&N,&M);
  163. for(int i = ; i <= N; i++){
  164. scanf("%d",a+i);
  165. r[i] = i;
  166. }
  167.  
  168. n_ = N;
  169. char ch[];
  170. for(int i = ; i < M; i++){
  171. scanf("%s",ch);
  172. if(*ch == 'Q') {
  173. scanf("%d%d%d",&qus[i].i,&qus[i].j,&qus[i].k);
  174. }
  175. else {
  176. qus[i].k = ++n_;
  177. r[n_] = n_;
  178. scanf("%d%d",&qus[i].i,a+n_);
  179. qus[i].j = -;
  180. }
  181. }
  182.  
  183. sort(r+,r+n_+,[](int i,int j){ return a[i]<a[j]; });
  184. mp_a[b[r[]] = ns = ] = a[r[]];
  185. for(int i = ; i <= n_; i++) {
  186. int k = r[i];
  187. if(a[k] != a[r[i-]]){
  188. mp_a[b[k] = ++ns] = a[k];
  189. }
  190. else {
  191. b[k] = ns;
  192. }
  193. }
  194. }
  195.  
  196. //#define LOCAL
  197. int main()
  198. {
  199. #ifdef LOCAL
  200. freopen("in.txt","r",stdin);
  201. #endif
  202. //cout<<ceil(log2(MAX_N+MAX_M))+1;
  203. //cout<<sizeof(Node*)<<endl;
  204. //cout<<MAX_ND<<endl;
  205. // cout<<MAX_ND*sizeof(Node)+(MAX_NM)*16+MAX_M*12+MAX_N*8;
  206. // cout<<sizeof(a)+sizeof(root)+sizeof(meo)+sizeof(qus)+sizeof(BIT)<<endl;//sizeof(b)+sizeof(mp_a)+sizeof(r)
  207. p[] = {,,};
  208. X.reserve(MAX_D+);
  209. Y.reserve(MAX_D+);
  210.  
  211. int T; scanf("%d",&T);
  212. while(T--){
  213. init();
  214. solve();
  215. }
  216. return ;
  217. }

ZOJ - 2112 Dynamic Rankings(BIT套主席树)的更多相关文章

  1. ZOJ 2112 Dynamic Rankings(二分,树套树)

    动态区间询问kth,单点修改. 区间用线段树分解,线段树上每条线段存一颗平衡树. 不能直接得到kth,但是利用val和比val小的个数之间的单调性,二分值.log^3N. 修改则是一次logN*log ...

  2. bzoj1901: Zju2112 Dynamic Rankings(BIT套主席树)

    带修改的题主席树不记录前缀,只记录单点,用BIT统计前缀.  对于BIT上每一个点建一棵主席树,修改和询问的时候用BIT跑,在主席树上做就行了.  3k4人AC的题#256...应该不算慢 #incl ...

  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. 整体二分&cdq分治 ZOJ 2112 Dynamic Rankings

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

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

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

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

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

  7. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  8. ZOJ 2112 Dynamic Rankings(树状数组+主席树)

    题意 \(n\) 个数,\(m\) 个操作,每次操作修改某个数,或者询问某个区间的第 \(K\) 小值. \(1 \leq n \leq 50000\) \(1 \leq m \leq 10000\) ...

  9. BZOJ 1901 洛谷 P2617 ZOJ 2112 Dynamic Rankings

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

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

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

随机推荐

  1. TCP/IP、Http、Https、Socket的区别

    网络由下往上分为物理层.数据链路层.网络层( IP协议).传输层( TCP协议).会话层.表示层和应用层(HTTP协议) 接下来我来说说个人理解其中的TCP/IP.Http.Socket的区别 TCP ...

  2. 树莓派安装摄像头 C110 motion

    ### 1.修改成国内的软件源,否则会失败或下载太慢sudo vi /etc/apt/sources.listdeb http://mirrors.aliyun.com/raspbian/raspbi ...

  3. vue(4)hello world

    在前一章基础上开发. 1.下载vue.js.(https://cn.vuejs.org/v2/guide/installation.html) 在hello-vue根目录下创建js文件夹,并将该vue ...

  4. spring boot+jaspersoft实现复杂报表

    1.实现效果: 2.下载 jaspersoft分为社区版和商业版,以下网址是社区版:https://community.jaspersoft.com/community-download

  5. 虚拟机 --- windows传输文件到虚拟机内

    安装xftp 如果未安装的,可以点击上图红框的图标,会有链接....下载时记得选择school那一个身份,这是免费的...邮箱必须要写,因为下载链接会发送到你的邮箱里,如果没收到就换一个邮箱 下载完后 ...

  6. 五种I/O模型的学习

    来自   http://www.52im.net/thread-1935-1-1.html 4.互联网服务端处理网络请求的原理 首先看看一个典型互联网服务端处理网络请求的典型过程:<ignore ...

  7. python 在windows下监听键盘按键

    python 在windows下监听键盘按键 使用到的库 ctypes(通过ctypes来调用Win32API, 主要就是调用钩子函数) 使用的Win32API SetWindowsHookEx(), ...

  8. Lua 遍历Linux目录下的文件夹

    代码如下,里面有注释,应该能看懂. function getFile(file_name) local f = assert(io.open(file_name, 'r')) local string ...

  9. Mvc内建功能(DefaultModelBinder)自动绑定。

    在做Asp.Net MVC项目中,都知道View负责页面展示数据或者提供页面收集数据,而所展示的数据或者收集的数据都是从Controller的Action中获取或提交到Controller的Actio ...

  10. js弹出页面

    建立一个HTML文件,输入以下代码就能弹出页面 <!DOCTYPE html> <html lang="en"> <head> <meta ...