BZOJ1901:

线段树套线段树做法:

(外层线段树 里层动态开节点的权值线段树)

有一个小小的trick 可以省掉二分变成nlog^2n的

就是把查询的区间都取出来… logn个一起走…

2016.2.14Upd

  1. //By SiriusRen
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. const int N=10050;
  7. int root[N*8],n,m,cnt,tot,base[N*2],L[N*200],R[N*200],tree[N*200],a[N],stk[N],top;
  8. struct Ask{char s[3];int i,j,k;}ask[N];
  9. void Insert(int l,int r,int &pos,int wei,int f){
  10. if(!pos)pos=++cnt;tree[pos]+=f;
  11. if(l==r)return;
  12. int mid=(l+r)>>1;
  13. if(mid<wei)Insert(mid+1,r,R[pos],wei,f);
  14. else Insert(l,mid,L[pos],wei,f);
  15. }
  16. void insert(int l,int r,int pos,int num,int wei,int f){
  17. Insert(1,tot,root[pos],wei,f);
  18. if(l==r)return;
  19. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  20. if(mid<num)insert(mid+1,r,rson,num,wei,f);
  21. else insert(l,mid,lson,num,wei,f);
  22. }
  23. void query(int l,int r,int pos,int L,int R){
  24. if(l>=L&&r<=R){stk[++top]=root[pos];return;}
  25. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  26. if(mid<L)query(mid+1,r,rson,L,R);
  27. else if(mid>=R)query(l,mid,lson,L,R);
  28. else query(l,mid,lson,L,R),query(mid+1,r,rson,L,R);
  29. }
  30. int Query(int xx,int yy,int kth){
  31. top=0,query(1,n,1,xx,yy);
  32. int l=1,r=tot;
  33. while(l<r){
  34. int temp=0;
  35. for(int i=1;i<=top;i++)temp+=tree[L[stk[i]]];
  36. if(temp>=kth){
  37. r=(l+r)>>1;
  38. for(int i=1;i<=top;i++)stk[i]=L[stk[i]];
  39. }
  40. else{
  41. l=(l+r)/2+1,kth-=temp;
  42. for(int i=1;i<=top;i++)stk[i]=R[stk[i]];
  43. }
  44. }
  45. printf("%d\n",base[l]);
  46. }
  47. int main(){
  48. scanf("%d%d",&n,&m);
  49. for(int i=1;i<=n;i++)scanf("%d",&a[i]),base[++tot]=a[i];
  50. for(int i=1;i<=m;i++){
  51. scanf("%s%d%d",ask[i].s,&ask[i].i,&ask[i].j);
  52. if(ask[i].s[0]=='Q')scanf("%d",&ask[i].k);
  53. else base[++tot]=ask[i].j;
  54. }
  55. sort(base+1,base+1+tot);tot=unique(base+1,base+1+tot)-base-1;
  56. for(int i=1;i<=n;i++)insert(1,n,1,i,lower_bound(base+1,base+1+tot,a[i])-base,1);
  57. for(int i=1;i<=m;i++){
  58. if(ask[i].s[0]=='Q')Query(ask[i].i,ask[i].j,ask[i].k);
  59. else{
  60. insert(1,n,1,ask[i].i,lower_bound(base+1,base+1+tot,a[ask[i].i])-base,-1);
  61. insert(1,n,1,ask[i].i,lower_bound(base+1,base+1+tot,ask[i].j)-base,1);
  62. a[ask[i].i]=ask[i].j;
  63. }
  64. }
  65. }

线段树+treap

  1. //By SiriusRen
  2. #include <cstdio>
  3. #include <algorithm>
  4. using namespace std;
  5. #define N 600050
  6. char op[3];
  7. int n,m,t,root[N],size,a[N],tmp,L,R,xx;
  8. struct Treap{int ch[2],v,cnt,rnd,sz;}tr[N];
  9. void Upd(int k){tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz+tr[k].cnt;}
  10. void rot(int &k,bool f){int t=tr[k].ch[f];tr[k].ch[f]=tr[t].ch[!f],tr[t].ch[!f]=k,Upd(k),Upd(t),k=t;}
  11. void insert(int &k,int num){
  12. if(!k){k=++size;tr[k].cnt=tr[k].sz=1,tr[k].rnd=rand(),tr[k].v=num;return;}
  13. tr[k].sz++;
  14. if(tr[k].v==num){tr[k].cnt++;return;}
  15. bool f=num>tr[k].v;
  16. insert(tr[k].ch[f],num);
  17. if(tr[tr[k].ch[f]].rnd<tr[k].rnd)rot(k,f);
  18. }
  19. void Build(int l,int r,int pos){
  20. insert(root[pos],a[t]);
  21. if(l==r)return;
  22. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  23. if(mid>=t)Build(l,mid,lson);
  24. else Build(mid+1,r,rson);
  25. }
  26. void query(int k,int num){
  27. if(!k)return;
  28. if(tr[k].v==num){tmp+=tr[tr[k].ch[0]].sz;return;}
  29. else if(tr[k].v>num)query(tr[k].ch[0],num);
  30. else tmp+=tr[tr[k].ch[0]].sz+tr[k].cnt,query(tr[k].ch[1],num);
  31. }
  32. void Query(int l,int r,int pos,int num){
  33. if(l>=L&&r<=R){query(root[pos],num);return;}
  34. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  35. if(mid<L)Query(mid+1,r,rson,num);
  36. else if(mid>=R)Query(l,mid,lson,num);
  37. else Query(l,mid,lson,num),Query(mid+1,r,rson,num);
  38. }
  39. void b_srch(){
  40. int l=0,r=0x3fffffff,Ans=0;
  41. while(l<=r){
  42. int mid=(l+r)>>1;
  43. tmp=1,Query(1,n,1,mid);
  44. if(tmp<=xx)Ans=mid,l=mid+1;
  45. else r=mid-1;
  46. }
  47. printf("%d\n",Ans);
  48. }
  49. void del(int &k,int num){
  50. if(tr[k].v==num){
  51. if(tr[k].cnt>1)tr[k].sz--,tr[k].cnt--;
  52. else if(tr[k].ch[0]*tr[k].ch[1]==0)k=tr[k].ch[0]+tr[k].ch[1];
  53. else rot(k,tr[tr[k].ch[0]].rnd>tr[tr[k].ch[1]].rnd),del(k,num);
  54. }
  55. else tr[k].sz--,del(tr[k].ch[num>tr[k].v],num);
  56. }
  57. void Change(int l,int r,int pos){
  58. del(root[pos],a[L]),insert(root[pos],xx);
  59. if(l==r)return;
  60. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  61. if(mid<L)Change(mid+1,r,rson);
  62. else Change(l,mid,lson);
  63. }
  64. int main(){
  65. scanf("%d%d",&n,&m);
  66. for(t=1;t<=n;t++)
  67. scanf("%d",&a[t]),Build(1,n,1);
  68. for(int i=1;i<=m;i++){
  69. scanf("%s",op);
  70. if(op[0]=='Q')scanf("%d%d%d",&L,&R,&xx),b_srch();
  71. else scanf("%d%d",&L,&xx),Change(1,n,1),a[L]=xx;
  72. }
  73. }

加个多case就是ZOJ2112了:

  1. //By SiriusRen
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. #define N 1000050
  7. char op[3];
  8. int n,m,t,root[50050*8],size,a[50050],tmp,L,R,xx,cases;
  9. struct Treap{int ch[2],v,cnt,rnd,sz;}tr[N];
  10. void Upd(int k){tr[k].sz=tr[tr[k].ch[0]].sz+tr[tr[k].ch[1]].sz+tr[k].cnt;}
  11. void rot(int &k,bool f){int t=tr[k].ch[f];tr[k].ch[f]=tr[t].ch[!f],tr[t].ch[!f]=k,Upd(k),Upd(t),k=t;}
  12. void insert(int &k,int num){
  13. if(!k){k=++size;tr[k].cnt=tr[k].sz=1,tr[k].rnd=rand(),tr[k].v=num;return;}
  14. tr[k].sz++;
  15. if(tr[k].v==num){tr[k].cnt++;return;}
  16. bool f=num>tr[k].v;
  17. insert(tr[k].ch[f],num);
  18. if(tr[tr[k].ch[f]].rnd<tr[k].rnd)rot(k,f);
  19. }
  20. void Build(int l,int r,int pos){
  21. insert(root[pos],a[t]);
  22. if(l==r)return;
  23. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  24. if(mid>=t)Build(l,mid,lson);
  25. else Build(mid+1,r,rson);
  26. }
  27. void query(int k,int num){
  28. if(!k)return;
  29. if(tr[k].v==num){tmp+=tr[tr[k].ch[0]].sz;return;}
  30. else if(tr[k].v>num)query(tr[k].ch[0],num);
  31. else tmp+=tr[tr[k].ch[0]].sz+tr[k].cnt,query(tr[k].ch[1],num);
  32. }
  33. void Query(int l,int r,int pos,int num){
  34. if(l>=L&&r<=R){query(root[pos],num);return;}
  35. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  36. if(mid<L)Query(mid+1,r,rson,num);
  37. else if(mid>=R)Query(l,mid,lson,num);
  38. else Query(l,mid,lson,num),Query(mid+1,r,rson,num);
  39. }
  40. void b_srch(){
  41. int l=0,r=0x3fffffff,Ans=0;
  42. while(l<=r){
  43. int mid=(l+r)>>1;
  44. tmp=1,Query(1,n,1,mid);
  45. if(tmp<=xx)Ans=mid,l=mid+1;
  46. else r=mid-1;
  47. }
  48. printf("%d\n",Ans);
  49. }
  50. void del(int &k,int num){
  51. if(tr[k].v==num){
  52. if(tr[k].cnt>1)tr[k].sz--,tr[k].cnt--;
  53. else if(tr[k].ch[0]*tr[k].ch[1]==0)k=tr[k].ch[0]+tr[k].ch[1];
  54. else rot(k,tr[tr[k].ch[0]].rnd>tr[tr[k].ch[1]].rnd),del(k,num);
  55. }
  56. else tr[k].sz--,del(tr[k].ch[num>tr[k].v],num);
  57. }
  58. void Change(int l,int r,int pos){
  59. del(root[pos],a[L]),insert(root[pos],xx);
  60. if(l==r)return;
  61. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  62. if(mid<L)Change(mid+1,r,rson);
  63. else Change(l,mid,lson);
  64. }
  65. int main(){
  66. scanf("%d",&cases);
  67. while(cases--){
  68. size=0,memset(root,0,sizeof(root));
  69. scanf("%d%d",&n,&m);
  70. for(int i=0;i<=n*20;i++)tr[i].ch[0]=tr[i].ch[1]=tr[i].v=tr[i].sz=tr[i].cnt=0;
  71. for(t=1;t<=n;t++)
  72. scanf("%d",&a[t]),Build(1,n,1);
  73. for(int i=1;i<=m;i++){
  74. scanf("%s",op);
  75. if(op[0]=='Q')scanf("%d%d%d",&L,&R,&xx),b_srch();
  76. else scanf("%d%d",&L,&xx),Change(1,n,1),a[L]=xx;
  77. }
  78. }
  79. }

BZOJ1901 ZOJ2112 线段树+treap (线段树套线段树)的更多相关文章

  1. 【学习笔记】浅析平衡树套线段树 & 带插入区间K小值

    常见的树套树 一般来说,在嵌套数据结构中,线段树多被作为外层结构使用. 但线段树毕竟是 静态 的结构,导致了一些不便. 下面是一个难以维护的例子: 带插入区间 \(k\) 小值问题 来源:Luogu ...

  2. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  3. bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1807  Solved: 772[Submit][Stat ...

  4. BZOJ_1901_&_ZJU_2112_Dynamic_Rankings_(主席树+树状数组/线段树+(Treap/Splay))

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1901 给出一个长度为n的数列A,有m次询问,询问分两种:1.修改某一位置的值;2.求区间[l, ...

  5. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  6. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  7. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  8. ZOJ-2112-Dynamic Rankings(线段树套splay树)

    题意: 完成两个操作: 1.询问一个区间里第k小的数: 2.修改数列中一个数的值. 分析: 线段树套平衡树,线段树中的每个节点都有一棵平衡树,维护线段树所记录的这个区间的元素.这样处理空间上是O(nl ...

  9. ZJOI 2017 树状数组(线段树套线段树)

    题意 http://uoj.ac/problem/291 思路 不难发现,九条カレン醬所写的树状数组,在查询区间 \([1,r]\) 的时候,其实在查询后缀 \([r,n]\) :在查询 \([l,r ...

随机推荐

  1. Centos6.6 系统优化

    1:最小化安装 2:修改网卡 vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0HWADDR=52:54:00:0e:c2:c3TYPE ...

  2. [TJOI2011]树的序(贪心,笛卡尔树)

    [TJOI2011]树的序 题目描述 众所周知,二叉查找树的形态和键值的插入顺序密切相关.准确的讲:1.空树中加入一个键值k,则变为只有一个结点的二叉查找树,此结点的键值即为k:2.在非空树中插入一个 ...

  3. python中的try...except...finally函数

    异常Error 我们在写代码的时候,经常会遇见程序抛出Error无法执行的情况 一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当Python脚本发 ...

  4. 【CS Round 34】Max Or Subarray

    [题目链接]:https://csacademy.com/contest/round-34/summary/ [题意] 让你找一个最短的连续子串; 使得这个子串里面所有数字or起来最大; [题解] 对 ...

  5. HDU——T 1150 Machine Schedule

    http://acm.hdu.edu.cn/showproblem.php?pid=1150 Time Limit: 2000/1000 MS (Java/Others)    Memory Limi ...

  6. Vue源代码笔记(一)数据绑定

    VUE数据绑定介绍 数据绑定是vue的基础核心之一,本文以Vue对象(当然也包含VueComponent)里的data数据绑定为例,阐述整个绑定的过程. Vue的数据绑定由三部分组成, Observe ...

  7. html+css实现选项卡功能

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. vim 插件之vim-trailing-whitespace

    vim-trailing-whitespace 这个插件是快速去掉文章行末的空格 地址 http://github.com/bronson/vim-trailing-whitespace 如果你想要使 ...

  9. 51nod-1296: 有限制的排列

    [传送门:51nod-1296] 简要题意: 有一个集合,集合中的数为1到n 给出a限制条件,a[i]表示第a[i]位置的数要比相邻位置的数要小 给出b限制条件,b[i]表示第b[i]位置的数要比相邻 ...

  10. ConfigurationSection

    https://msdn.microsoft.com/en-us/library/system.configuration.configurationsection(v=vs.110).aspx Re ...