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

题意:给你一个长为n的区间,有m个询问和修改,每次把下标i对应的值改变,或者询问某段区间的第k小值。

思路:这题是很经典的题,可以用主席树和树套树做,对于树套树的做法,我是用线段树的每一个节点都存一个treap,然后每一次修改就是单点更新,修改的时间复杂度为O(n*logn*logn),询问时,需要二分值val,并统计线段树中对应的区间小于val值的个数,询问的时间复杂度为O(n*logn*logn*logn),所以总的时间复杂度为O(n*logn*logn*logn),同时因为线段树最多有logn层,每层都是n个节点,所以treap的空间复杂度为O(n*logn).

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 50005
int rt[maxn*4],a[maxn],n;
int cnt;
struct Treap{
int key,pri,siz,num,son[2];
void newnode(int x,int y){
key=x;pri=y;
siz=num=1;
son[0]=son[1]=0;
}
}T[20*maxn]; void rotate(int p,int &x)
{
int y=T[x].son[!p];
T[x].siz=T[x].siz-T[y].siz+T[T[y].son[p] ].siz;
T[x].son[!p]=T[y].son[p];
T[y].siz=T[y].siz-T[T[y].son[p] ].siz+T[x].siz;
T[y].son[p]=x;
x=y;
} void charu(int key,int &x)
{
if(x==0){
x=++cnt;
T[x].newnode(key,rand());
}
else{
T[x].siz++;
if(T[x].key==key){
T[x].num++;return;
}
int p=key<T[x].key;
charu(key,T[x].son[!p]);
if(T[x].pri<T[T[x].son[!p] ].pri )
rotate(p,x);
}
}
void del(int key, int &x)
{
if(T[x].key == key)
{
if(T[x].num>1){
T[x].siz--;
T[x].num--;
return;
}
if(T[x].son[0] && T[x].son[1])
{
int p=T[T[x].son[0]].pri>T[T[x].son[1]].pri;
rotate(p,x);
del(key,x);
}
else x=T[x].son[1]+T[x].son[0];
}
else
{
T[x].siz--;
int p=T[x].key>key;
del(key,T[x].son[!p]);
}
}
int query_rank(int key,int &x)
{
if(x==0)return 0;
if(T[x].key==key)return T[T[x].son[0] ].siz;
if(T[x].key>key)return query_rank(key,T[x].son[0]);
if(T[x].key<key)return T[T[x].son[0] ].siz+T[x].num+query_rank(key,T[x].son[1]);
} void update(int idx,int val,int L,int R,int th,int f)
{
if(f)del(a[idx],rt[th]);
charu(val,rt[th]);
if(L==idx && R==idx){
a[idx]=val;
return;
}
int mid=(L+R)/2;
if(idx<=mid)update(idx,val,L,mid,lson,f);
else update(idx,val,mid+1,R,rson,f);
} int question(int l,int r,int val,int L,int R,int th)
{
int mid;
if(l==L && r==R){
return query_rank(val,rt[th]);
}
mid=(L+R)/2;
if(r<=mid)return question(l,r,val,L,mid,lson);
else if(l>mid)return question(l,r,val,mid+1,R,rson);
else return question(l,mid,val,L,mid,lson)+question(mid+1,r,val,mid+1,R,rson);
} int main()
{
int m,i,j,Tcase,l,r,c,d,e,mid;
char s[10];
scanf("%d",&Tcase);
while(Tcase--)
{
memset(rt,0,sizeof(rt));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
cnt=0;
for(i=1;i<=n;i++){
update(i,a[i],1,n,1,0);
}
for(i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d",&c,&d);
update(c,d,1,n,1,1);
}
else{
scanf("%d%d%d",&c,&d,&e);
l=0;r=1000000000;
while(l<=r){
mid=(l+r)/2;
//printf("%d %d %d\n",l,r,mid);
if(question(c,d,mid,1,n,1)>=e)r=mid-1;
else l=mid+1;
}
printf("%d\n",r);
}
} }
return 0;
} /*
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
*/

主席树做法:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define lth th<<1
#define rth th<<1|1
#define inf 99999999
#define pi acos(-1.0)
#define maxn 60005
#define M 2500010
int a[maxn],n;
struct node{
int l,r,kind,d;
}ques[10005];
int pos[maxn],T[maxn],S[maxn];
int lson[M],rson[M],c[M];
int th,tot; int build(int l,int r)
{
int newroot=++th,i,j,mid;
c[newroot]=0; //!!!
if(l!=r){
mid=(l+r)/2;
lson[newroot]=build(l,mid);
rson[newroot]=build(mid+1,r);
}
return newroot;
} int update(int root,int zhi,int value)
{
int i,j;
int newroot=++th;int tmp=newroot;
int l=1,r=tot,mid;
c[newroot]=c[root]+value;
while(l<r){
mid=(l+r)/2;
if(zhi<=mid){
r=mid;
lson[newroot ]=++th;rson[newroot]=rson[root];
newroot=lson[newroot];root=lson[root];
}
else{
l=mid+1;
lson[newroot ]=lson[root];rson[newroot]=++th;
newroot=rson[newroot];root=rson[root];
}
c[newroot]=c[root]+value;
}
return tmp;
} int lowbit(int x)
{
return x&(-x);
} void modify(int pos,int zhi,int value)
{
int i,j;
while(pos<=n){
S[pos]=update(S[pos],zhi,value);
pos+=lowbit(pos);
}
}
int use[maxn];
int getsum(int pos)
{
int sum=0;
while(pos>0){
sum+=c[lson[use[pos] ] ];
pos-=lowbit(pos);
}
return sum; }
int question(int left,int right,int k)
{
int i,j,root1,root2;
int l=1,r=tot,mid;
for(i=left-1;i>0;i-=lowbit(i))use[i]=S[i];
for(i=right;i>0;i-=lowbit(i))use[i]=S[i];
root1=T[left-1];root2=T[right]; while(l<r){
mid=(l+r)/2;
int tmp=getsum(right)-getsum(left-1)+c[lson[root2] ]-c[lson[root1] ];
if(tmp>=k){
r=mid;
root1=lson[root1];root2=lson[root2];
for(i=left-1;i>0;i-=lowbit(i))use[i]=lson[use[i] ];
for(i=right;i>0;i-=lowbit(i))use[i]=lson[use[i] ];
}
else{
k-=tmp;
l=mid+1;
root1=rson[root1];root2=rson[root2];
for(i=left-1;i>0;i-=lowbit(i))use[i]=rson[use[i] ];
for(i=right;i>0;i-=lowbit(i))use[i]=rson[use[i] ];
}
}
return l;
} int main()
{
int m,i,j,Tcase,c,d,e;
char str[5];
scanf("%d",&Tcase);
while(Tcase--)
{
scanf("%d%d",&n,&m);
tot=0;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
tot++;
pos[tot]=a[i];
}
for(i=1;i<=m;i++){
scanf("%s",str);
if(str[0]=='Q'){
scanf("%d%d%d",&c,&d,&e);
ques[i].kind=0;ques[i].l=c;ques[i].r=d;ques[i].d=e;
}
else if(str[0]=='C'){
scanf("%d%d",&c,&d);
tot++;pos[tot]=d;
ques[i].kind=1;ques[i].l=c;ques[i].r=d;
}
} sort(pos+1,pos+1+tot);
tot=unique(pos+1,pos+1+tot)-pos-1; th=0;
T[0]=build(1,tot); for(i=1;i<=n;i++){
int t=lower_bound(pos+1,pos+1+tot,a[i])-pos;
T[i]=update(T[i-1],t,1);
} for(i=1;i<=n;i++){
S[i]=T[0];
}
for(i=1;i<=m;i++){
if(ques[i].kind==0){ //表示询问
printf("%d\n",pos[question(ques[i].l,ques[i].r,ques[i].d)]);
}
else{
int t1=lower_bound(pos+1,pos+1+tot,a[ques[i].l])-pos;
int t2=lower_bound(pos+1,pos+1+tot,ques[i].r)-pos;
modify(ques[i].l,t1,-1);
modify(ques[i].l,t2,1);
a[ques[i].l ]=ques[i].r; //!!!
}
} }
return 0;
} /*
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
*/

zoj2112 Dynamic Rankings (主席树 || 树套树)的更多相关文章

  1. ZOJ2112 Dynamic Rankings (线段树套平衡树)(主席树)

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

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

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

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

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

  4. 【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组

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

  5. 洛谷P2617 Dynamic Rankings (主席树)

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

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

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

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

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

  8. ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大

    Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...

  9. ZOJ2112 Dynamic Rankings(整体二分)

    今天学习了一个奇技淫巧--整体二分.关于整体二分的一些理论性的东西,可以参见XRH的<浅谈数据结构题的几个非经典解法>.然后下面是一些个人的心得体会吧,写下来希望加深一下自己的理解,或者如 ...

随机推荐

  1. Mac上最好用的软件集合,没有之一

    前言 题主从 windows 系统换成 macOS 系统已经4年多了.对于没有用过 Mac 电脑的人来说,可能无法理解 Mac 好用在哪里.不过对于一个用过 Mac 的开发者来说,从 windows ...

  2. 【Java】面向对象

    重新搞一波 复习巩固 简单记录 慕课网 imooc Java 零基础入门-Java面向对象-面向对象 都是视频课件里的. 文章目录 面向对象 什么是对象 什么是面向对象 类 什么是对象的属性和方法 类 ...

  3. 跨平台导PDF,结合wkhtmltopdf很顺手

    前言 好东西要分享,之前一直在使用wkhtmltopdf进行pdf文件的生成,常用的方式就是先安装wkhtmltopdf,然后在程序中用命令的方式将对应的html生成pdf文件,简单而且方便:但重复的 ...

  4. 2021 Duilib最新入门教程(一)Duilib简介

    目录 Duilib解决什么问题? 方案一.自己画界面 方案二.使用标准控件 方案三.使用Duilib框架 Duilib是什么? 先看下Duilib官方简介 再看下DirectUI 百度百科   比起介 ...

  5. 1.8V转3V,1,8V转3.3V电源芯片的规格书参数

    1.8V电平如何稳压稳定输出3V或者3.3V,就需要用到1.8V转3V,1,8V转3.3V电源芯片,就PW5100(低功耗,外围简单),PW5200A是可调输出电压,可以输出电压根据外围电阻来设置命令 ...

  6. uni-app 开发随笔(踩坑记录)

    这里总结一些uni-app开发时我遇到的坑 uni-app获取元素高度及屏幕高度(uni-app不可使用document) uni.getSystemInfo({ success: function( ...

  7. .NET 中依赖注入组件 Autofac 的性能漫聊

    Autofac 是一款超赞的 .NET IoC 容器 ,在众多性能测评中,它也是表现最优秀的一个.它管理类之间的依赖关系, 从而使 应用在规模及复杂性增长的情况下依然可以轻易地修改.它的实现方式是将常 ...

  8. python基础之 列表、元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码

    本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 ...

  9. In Search of an Understandable Consensus Algorithm" (https://raft.github.io/raft.pdf) by Diego Ongaro and John Ousterhout.

    In Search of an Understandable Consensus Algorithm" (https://raft.github.io/raft.pdf) by Diego ...

  10. 每天响应数亿次请求,腾讯云如何提供高可用API服务?

    每天响应数亿次请求,腾讯云如何提供高可用API服务? https://mp.weixin.qq.com/s/OPwlHcqkaTT_gcwHfr5Shw 李阳 云加社区 2020-09-16 导语 | ...