Description
给出一个长度为n的序列a,两种操作
C x v:将第x个元素的值改成v
Q l r k:查询区间[l,r]中第k大的元素
Input
第一行为一个整数t表示用例组数,每组用例第一行为两个整数n和m分别表示序列长度和操作数,第二行n个整数表示序列a,之后m行每行一种操作
(0< t<=4,1<=n<=50000,1<=m<=10000)
Output
对于每次查询,输出查询结果
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
Solution
主席树动态第k大,设序列与操作中不同的数有s个,如果完全使用动态主席树,空间复杂度为O((n+m)*log n*log s),在这道题的内存限制下开不下这么大的数组,所以需要建两种主席树,第一种就是静态主席树维护每个前缀序列,第二种的动态主席树维护修改操作,每次查询时对这两棵树分别查询然后做和即可,这样的空间复杂度为O(nlog s+m*log n*log s)
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 50005
#define lowbit(x) (x&(-x))
struct Tree
{int left,right,data;
}T[50*maxn];
int t,n,m,a[maxn],b[2*maxn],pos[maxn],root[2*maxn],L[maxn],R[maxn],K[maxn],tot,cnt,res;
char O[maxn];
vector<int>p,q;
void build(int &i,int x,int l,int r)
{T[++tot]=T[i];i=tot;T[i].data++;if(l==r) return ;int mid=(l+r)>>1;if(x<=mid) build(T[i].left,x,l,mid);else build(T[i].right,x,mid+1,r);
}
void insert(int &i,int x,int y,int l,int r)
{T[++tot]=T[i];i=tot;T[i].data+=y;if(l==r) return ;int mid=(l+r)>>1;if(x<=mid)  insert(T[i].left,x,y,l,mid);else insert(T[i].right,x,y,mid+1,r);
}
void bit_insert(int i,int x,int y)
{while(i<=n){insert(root[i],x,y,1,res);i+=lowbit(i);}
}
int query(int k,int l,int r)
{if(l==r) return l;int mid=(l+r)>>1,cnt1=0,cnt2=0;for(int i=0;i<p.size();i++) cnt1+=T[T[p[i]].left].data;for(int i=0;i<q.size();i++) cnt2+=T[T[q[i]].left].data;if(cnt2-cnt1>=k){for(int i=0;i<p.size();i++) p[i]=T[p[i]].left;for(int i=0;i<q.size();i++) q[i]=T[q[i]].left;return query(k,l,mid);}else{for(int i=0;i<p.size();i++) p[i]=T[p[i]].right;for(int i=0;i<q.size();i++) q[i]=T[q[i]].right;return query(k-(cnt2-cnt1),mid+1,r);}
}
int solve(int l,int r,int k)
{p.clear();q.clear();if(l>0) p.push_back(root[l+n]);//若l=0则不能将root[n]加到p中 q.push_back(root[r+n]);while(l>0){p.push_back(root[l]);l-=lowbit(l);}while(r>0){q.push_back(root[r]);r-=lowbit(r);}return query(k,1,res);
}
int main()
{scanf("%d",&t);while(t--){tot=cnt=0;memset(root,0,sizeof(root));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[++cnt]=a[i];for(int i=1;i<=m;i++){char op[11];scanf("%s%d%d",op,&L[i],&R[i]);O[i]=op[0];if(op[0]=='Q') scanf("%d",&K[i]);else b[++cnt]=R[i];}sort(b+1,b+cnt+1); res=unique(b+1,b+cnt+1)-b-1;//利用去重函数得到节点数 for(int i=1;i<=n;i++) pos[i]=lower_bound(b+1,b+res+1,a[i])-b;//pos记录每个值在主席树中的位置 for(int i=1;i<=n;i++){root[i+n]=root[i+n-1];build(root[i+n],pos[i],1,res);//建主席树 }for(int i=1;i<=m;i++){if(O[i]=='C'){bit_insert(L[i],pos[L[i]],-1);//消除原先值的影响 pos[L[i]]=lower_bound(b+1,b+res+1,R[i])-b;//更新pos值 bit_insert(L[i],pos[L[i]],1);//加入更新值的影响 }else{int ans=solve(L[i]-1,R[i],K[i]); printf("%d\n",b[ans]);}}}return 0;
}

ZOJ 2112 Dynamic Rankings(主席树-动态第k大)相关推荐

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

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

  2. zoj - 2112 带修改主席树 + 空间优化

    ZOJ - 2112 题意:求区间第k小 思路:带修改区间第k小裸题,无修改的主席树是维护一个前缀线段树,每次更新log个节点,用root 和 ls rs作为每颗前缀线段树的根节点和左右子树的索引(相 ...

  3. ZOJ 2112 Dynamic Rankings

    这里是题目地址 其实就是带修改的区间第K大. 写了一下BIT套主席树,内存飞起,似乎需要特别的优化技巧 = = 所以还是写了一下线段树套平衡树,跑了1s左右. 其实线段树套平衡树就是归并树的自然扩展而 ...

  4. hdu 2665(主席树查询区间k大值)

    先贴我自己写的代码做模板虽然跟原博主没什么两样.(一开始空间开的4*maxn,交到hdu上一直TLE很奇怪) #include<bits/stdc++.h> using namespace ...

  5. Dynamic Rankings——带修改区间第k大

    三种做法: 1.整体二分: 二分mid 考虑小于mid的修改的影响 但是大于mid的修改可能会干掉小于mid的一些值 所以额外把一个修改变成一个值的删除和一个值的添加 这样就相互独立了! 整体二分,树 ...

  6. POJ 2104 K-th Number 主席树(区间第k大)

    题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...

  7. zoj 2112 树状数组 套主席树 动态求区间 第k个数

    总算是把动态求区间第k个数的算法看明白了. 在主席树的基础上,如果有修改操作,则要通过套树状数组来实现任意区间求第k小的问题. 刚开始看不明白什么意思,现在有一点理解.树状数组的每个元素是一个线段树, ...

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

    Time:2016.05.09 Author:xiaoyimi 转载注明出处谢谢 传送门(权限) 题面 1901: Zju2112 Dynamic Rankings Time Limit: 10 Se ...

  9. 树套树 ---- 树状数组套权值线段树模板题 P2617 Dynamic Rankings 动态第K大

    题目链接 题目大意: 给你一个数组aaa,aaa有两个操作 询问aaa中[l,r][l,r][l,r]区间里面第kkk小的数是哪个? 修改axa_xax​为yyy 解题思路: 首先我们知道权值线段树是 ...

最新文章

  1. java-unrar-0.3.jar_unrar.jar解压缩rar文件
  2. 多继承中构造器和析构器的调用顺序
  3. 2021阿里云开发者大会|【云原生数据库:一站式数据服务】分论坛即将开启
  4. oracle 查看数据库性能,oracle 11G使用statspack查看数据库的性能
  5. 【第2篇】Python爬虫实战-PPT模板素材下载
  6. 生成注释_SOLIDWORKS DimXpert 自动生成注释
  7. Linux作者批评英特尔指令集,Linux之父炮轰英特尔:ECC内存很重要,不好买都怪你胡搞...
  8. 《精进:如何成为一个很厉害的人》
  9. mysql宠物销售系统论文,宠物店管理系统的设计与实现.doc
  10. 【教程】如何批量图片文字识别软件,批量图片文字识别OCR软件系统,批量图片压缩,PDF批量转文字转图片
  11. 【吴恩达deeplearning.ai】Course 5 - 2.10 词嵌入除偏
  12. 为知笔记-艾宾浩斯遗忘曲线复习插件
  13. 拼音转换成汉字html,汉字转成拼音-用HTML实现
  14. 【超详细】全国大学生软件测试大赛:移动应用测试参赛指南
  15. Polkadot波卡链众筹成本价与总量、创始人团队简介
  16. 百度文库文件等待下载
  17. uap 自动生成场景代码
  18. 基于安卓的公司员工考勤系统的设计与实现
  19. 计算机应用决策支持系统,决策支持系统
  20. 一步一步学Spring Boot(三)-黄文毅-专题视频课程

热门文章

  1. 不同进制之间的转换(完整版)
  2. K12在线教育发展前景分析
  3. 电脑qq浏览器怎么滚动截长图_Mac系统如何轻松实现网页长截图功能
  4. Let‘s Encrypt 安装配置教程
  5. 项目管理(PMP)真题解析(一)
  6. 泰课在线Unity3d 动作游戏全攻略——有素材和代码
  7. 一个前JDer对京东的祝福,愿你越来越好!
  8. PHP如何给整个内容填充背景,如何给文字添加背景图?给文字填充图片背景色的操作方法...
  9. Windows平台的原始套接字编程的知识点概要(备忘)
  10. 迈克尔•波特的“五力模型”中,最明显的竞争状态是()国开个人与团队管理知识点解析