【BZOJ1901】Zju2112 Dynamic Rankings

Description

给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。

Input

第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。

Output

对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

Sample Input

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

Sample Output

3
6

HINT

20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。

题解:对于动态修改的问题,我们采用树状数组套主席树的做法(但还是离线)。什么叫树状数组套主席树呢?

就是正常的主席树每棵线段树保存的是[1,i]这个区间,而这里的主席树相当于保存的相当于树状数组上[1,i-lowbit+1]+...+[1,i]这些线段树的和,所以我们在查询的时候就要同时在logn棵线段树上查询。那么在修改时我们每修改一个数,也要新建logn棵线段树。

还有注意这题是a[i]可以等于0

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. using namespace std;
  6. const int maxn=20010;
  7. int n,m,tot,nm,ta,tb;
  8. struct NUM
  9. {
  10. int num,org;
  11. }v[maxn];
  12. struct NODE
  13. {
  14. int ls,rs,siz;
  15. }s[maxn*200];
  16. int qa[maxn],qb[maxn],qc[maxn],qk[maxn],ref[maxn],root[maxn];
  17. int now[maxn],pos[maxn],val[maxn],sa[maxn],sb[maxn];
  18. char str[5];
  19. bool cmp1(NUM a,NUM b)
  20. {
  21. return a.num<b.num;
  22. }int readin()
  23. {
  24. int ret=0,f=1; char gc=getchar();
  25. while(gc<'0'||gc>'9'){if(gc=='-')f=-f; gc=getchar();}
  26. while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
  27. return ret*f;
  28. }
  29. void insert(int x,int &y,int l,int r,int p,int q)
  30. {
  31. y=++tot;
  32. if(l==r)
  33. {
  34. s[y].siz=s[x].siz+q;
  35. return ;
  36. }
  37. int mid=l+r>>1;
  38. if(p<=mid) s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,p,q);
  39. else s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,p,q);
  40. s[y].siz=s[s[y].ls].siz+s[s[y].rs].siz;
  41. }
  42. int query(int l,int r,int p)
  43. {
  44. if(l==r) return ref[l];
  45. int i,suma=0,sumb=0;
  46. int mid=l+r>>1;
  47. for(i=1;i<=ta;i++) suma+=s[s[sa[i]].ls].siz;
  48. for(i=1;i<=tb;i++) sumb+=s[s[sb[i]].ls].siz;
  49. if(sumb-suma>=p)
  50. {
  51. for(i=1;i<=ta;i++) sa[i]=s[sa[i]].ls;
  52. for(i=1;i<=tb;i++) sb[i]=s[sb[i]].ls;
  53. return query(l,mid,p);
  54. }
  55. else
  56. {
  57. for(i=1;i<=ta;i++) sa[i]=s[sa[i]].rs;
  58. for(i=1;i<=tb;i++) sb[i]=s[sb[i]].rs;
  59. return query(mid+1,r,p-sumb+suma);
  60. }
  61. }
  62. int main()
  63. {
  64. n=readin(),m=readin();
  65. int i,j,a,b,pre;
  66. for(i=1;i<=n;i++) v[++nm].num=readin(),v[nm].org=nm;
  67. for(i=1;i<=m;i++)
  68. {
  69. scanf("%s",str);
  70. qa[i]=readin(),qb[i]=readin();
  71. if(str[0]=='Q') qc[i]=readin();
  72. else v[++nm].num=qb[i],v[nm].org=n+i,qk[i]=1;
  73. }
  74. sort(v+1,v+nm+1,cmp1);
  75. for(ref[pre=0]=-1,i=1;i<=nm;i++)
  76. {
  77. if(v[i].num>ref[pre]) ref[++pre]=v[i].num;
  78. if(v[i].org>n) qb[v[i].org-n]=pre;
  79. else val[v[i].org]=pre;
  80. }
  81. for(i=1;i<=n;i++)
  82. for(j=i;j<=n;j+=j&-j)
  83. insert(root[j],root[j],1,nm,val[i],1);
  84. for(i=1;i<=m;i++)
  85. {
  86. if(qk[i]==1)
  87. {
  88. for(j=qa[i];j<=n;j+=j&-j) insert(root[j],root[j],1,nm,val[qa[i]],-1);
  89. val[qa[i]]=qb[i];
  90. for(j=qa[i];j<=n;j+=j&-j) insert(root[j],root[j],1,nm,qb[i],1);
  91. }
  92. else
  93. {
  94. for(ta=0,j=qa[i]-1;j;j-=j&-j) sa[++ta]=root[j];
  95. for(tb=0,j=qb[i];j;j-=j&-j) sb[++tb]=root[j];
  96. printf("%d\n",query(1,nm,qc[i]));
  97. }
  98. }
  99. }

【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组的更多相关文章

  1. BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6058 Solved: 2521 [Su ...

  2. BZOJ1901 Zju2112 Dynamic Rankings 主席树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1901 题意概括 给你一段序列(n个数),让你支持一些操作(共m次), 有两种操作,一种是询问区间第 ...

  3. BZOJ1901: Zju2112 Dynamic Rankings(整体二分 树状数组)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9094  Solved: 3808[Submit][Status][Discuss] Descript ...

  4. [BZOJ1901]Zju2112 Dynamic Rankings

    [BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...

  5. Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6321  Solved: 2628[Su ...

  6. bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

  7. [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】

    题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...

  8. BZOJ1901 Zju2112 Dynamic Rankings 【树状数组套主席树】

    题目 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k≤j- ...

  9. [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)

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

随机推荐

  1. each,collect map collect! map!

    arr = [1,2,3] 1) arr2 = arr.each{|element| element = element * 2} #arr与arr2仍然都等于[1,2,3]   each返回原数组 ...

  2. 简单十招提高jQuery执行效率

    1. 使用最新版本的jQuery jQuery的版本更新很快,你应该总是使用最新的版本.因为新版本会改进性能,还有很多新功能. 下面就来看看,不同版本的jQuery性能差异有多大.这里是三条最常见的j ...

  3. openfire url get提交 中文乱码问题

    原因是它只接受url编码后的中文 如:%E7%BC%96%E7%A0%81%E5%90%8E%E7%9A%84%E4%B8%AD%E6%96%87 会自动转变为:http://127.0.0.1:90 ...

  4. java_Observer Design Pattern

    摘自: http://www.ntu.edu.sg/home/ehchua/programming/java/J4a_GUI.html Creating Your Own Event, Source ...

  5. 第三百零八节,Django框架,models.py模块,数据库操作——链表结构,一对多、一对一、多对多

    第三百零八节,Django框架,models.py模块,数据库操作——链表结构,一对多.一对一.多对多 链表操作 链表,就是一张表的外键字段,连接另外一张表的主键字段 一对多 models.Forei ...

  6. python读写word文档

    读: from docx import Document dir_docx = 'F:\Eclipse\workspace\Spider\cnblogs_doc\mytest - 副本.docx' d ...

  7. python3.4连接mysql

    参考:http://www.blogjava.net/huyi2006/articles/247966.html 开发环境:win7_x64 + python3.4.3 + mysql5.6.23 准 ...

  8. 【Java面试题】59 Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

    Math类中提供了三个与取整有关的方法:ceil.floor.round,这些方法的作用与它们的英文名称的含义相对应,例如,ceil的英文意义是天花板,该方法就表示向上取整,Math.ceil(11. ...

  9. 【Java集合的详细研究6】Java 数组

    Java 语言中提供的数组是用来存储固定大小的同类型元素. 声明数组变量 double[] myList; // 首选的方法 或 double myList[]; // 效果相同,但不是首选方法 创建 ...

  10. Eclipse的调试功能的10个小窍门

    你可能已经看过一些类似“关于调试的N件事”的文章了.但我想我每天大概在调试上会花掉1个小时,这是非常多的时间了.所以非常值得我们来了解一些用得到的功能,可以帮我们节约很多时间.所以在这个主题上值得我再 ...