Dynamic Rankings


Time Limit: 10 Seconds      Memory Limit: 32768 KB

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

  不知道为何,ZOJ上交这道题要FQ,BZOJ上有这道题,还TM是权限题,估计是偷的(鄙视BZOJ)。

  因为有修改操作,考虑保持原有的主席树结构,假设i位置上的数变化,那么要修改主席树中i及i以后的位置,如果一个一个修改肯定超时,可以考虑将修改的时间摊到查询上去,用Bit维护修改操作,记为前缀和,很好脑补。

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=;
const int maxm=;
int tot,cnt,hash[maxn],a[maxn];
int sum[maxm],ch[maxm][],rt[maxn],bit[maxn];
int use[maxn],n;
struct Ask{
int l,r,k;
}q[maxn]; void Insert(int pre,int &rt,int l,int r,int g,int d){
rt=++cnt;
ch[rt][]=ch[pre][];
ch[rt][]=ch[pre][];
sum[rt]=sum[pre]+d;
if(l==r)return;
int mid=(l+r)>>;
if(mid>=g)Insert(ch[pre][],ch[rt][],l,mid,g,d);
else Insert(ch[pre][],ch[rt][],mid+,r,g,d);
} void Modify(int p,int g,int d){
while(p<=n){
Insert(bit[p],bit[p],,tot,g,d);
p+=p&(-p);
}
} int Query(int pre,int rt,int l,int r,int k,int L,int R){
if(l==r)return l;
int mid=(l+r)>>,p=R,c=;
while(p){c+=sum[ch[use[p]][]];p-=p&(-p);}p=L-;
while(p){c-=sum[ch[use[p]][]];p-=p&(-p);}
c+=sum[ch[rt][]]-sum[ch[pre][]];
if(c>=k){
p=R;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}p=L-;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}
return Query(ch[pre][],ch[rt][],l,mid,k,L,R);
}
else{
k-=c;p=R;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}p=L-;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}
return Query(ch[pre][],ch[rt][],mid+,r,k,L,R);
} } int Solve(int l,int r,int k){
int p=l-;
while(p){use[p]=bit[p];p-=p&(-p);}p=r;
while(p){use[p]=bit[p];p-=p&(-p);}
return Query(rt[l-],rt[r],,tot,k,l,r);
} void Init(){
memset(rt,,sizeof(rt));cnt=;
memset(bit,,sizeof(bit));
} bool cmp(int a,int b){
return a>b;
}
char op[];
int main(){
int T,Q;
scanf("%d",&T);
while(T--){
Init();
scanf("%d%d",&n,&Q);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
tot=n;
for(int i=;i<=Q;i++){
scanf("%s",op);
if(op[]=='Q')
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
else{
scanf("%d%d",&q[i].l,&q[i].k);
a[++tot]=q[i].k;q[i].r=-;
}
}
for(int i=;i<=tot;i++)
hash[i]=a[i];
sort(hash+,hash+tot+);
for(int i=;i<=tot;i++)
a[i]=lower_bound(hash+,hash+tot+,a[i])-hash; for(int i=;i<=n;i++)
Insert(rt[i-],rt[i],,tot,a[i],);
for(int i=,head=n;i<=Q;i++){
if(q[i].r==-){
Modify(q[i].l,a[q[i].l],-);
Modify(q[i].l,a[++head],);
a[q[i].l]=a[head];
}
else
printf("%d\n",hash[Solve(q[i].l,q[i].r,q[i].k)]);
}
}
return ;
}

2016年6月9日重打了一遍……

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
const int maxm=;
char op[];
int n,Q,T,use[maxn];
int qa[maxn],qb[maxn],qk[maxn];
int tot,cnt,ch[maxm][],sum[maxm];
int a[maxn],hash[maxn],bit[maxn],rt[maxn];
void Insert(int pre,int &rt,int l,int r,int g,int d){
rt=++cnt;
ch[rt][]=ch[pre][];
ch[rt][]=ch[pre][];
sum[rt]=sum[pre]+d;
if(l==r)return;
if(l+r>>>=g)Insert(ch[pre][],ch[rt][],l,l+r>>,g,d);
else Insert(ch[pre][],ch[rt][],(l+r>>)+,r,g,d);
}
void Modify(int p,int g,int d){
while(p<=n){
Insert(bit[p],bit[p],,tot,g,d);
p+=p&(-p);
}
}
int Query(int pre,int rt,int l,int r,int k,int L,int R){
if(l==r)return l;
int c=sum[ch[rt][]]-sum[ch[pre][]],p=R;
while(p){c+=sum[ch[use[p]][]];p-=p&(-p);}p=L-;
while(p){c-=sum[ch[use[p]][]];p-=p&(-p);}
if(c>=k){p=R;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}p=L-;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}
return Query(ch[pre][],ch[rt][],l,l+r>>,k,L,R);
}
else{p=R;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}p=L-;
while(p){use[p]=ch[use[p]][];p-=p&(-p);}
return Query(ch[pre][],ch[rt][],(l+r>>)+,r,k-c,L,R);
}
}
int Solve(int i){
int p=qb[i];
while(p){use[p]=bit[p];p-=p&(-p);}p=qa[i]-;
while(p){use[p]=bit[p];p-=p&(-p);}
return Query(rt[qa[i]-],rt[qb[i]],,tot,qk[i],qa[i],qb[i]);
}
void Init(){
memset(bit,,sizeof(bit));
cnt=;tot=n;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("dynrank.in","r",stdin);
freopen("dynrank.out","w",stdout);
#endif
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&Q);Init();
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
hash[i]=a[i];
}
for(int i=;i<=Q;i++){
scanf("%s",op);
if(op[]=='Q')scanf("%d%d%d",&qa[i],&qb[i],&qk[i]);
else{
scanf("%d%d",&qa[i],&qk[i]);
tot++;hash[tot]=a[tot]=qk[i];qb[i]=-;
}
}
sort(hash+,hash+tot+);
for(int i=;i<=tot;i++)
a[i]=lower_bound(hash+,hash+tot+,a[i])-hash;
for(int i=;i<=n;i++)Insert(rt[i-],rt[i],,tot,a[i],);
for(int i=,p=n;i<=Q;i++){
if(qb[i]==-){
Modify(qa[i],a[qa[i]],-);
Modify(qa[i],a[++p],);
a[qa[i]]=a[p];
}
else
printf("%d\n",hash[Solve(i)]);
}
}
return ;
}

  还打了一个强大的整体二分。

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
int T,n,Q,cntQ;
int num[maxn],ans[maxn],bit[maxn];
char op[];
struct Node{
int x,y,k,id,tp;
}a[maxn],t1[maxn],t2[maxn];
//tp==1 add; tp==2 del; tp==3 query; void Add(int x,int d){
while(x<=n){
bit[x]+=d;
x+=x&(-x);
}
} int Query(int x){
int ret=;
while(x){
ret+=bit[x];
x-=x&(-x);
}
return ret;
} void Solve(int h,int t,int l,int r){
if(l==r){
for(int i=h;i<=t;i++)
if(a[i].tp==)ans[a[i].id]=l;
return;
}
if(h>t)return;
int p1=,p2=,d;
for(int i=h;i<=t;i++){
if(a[i].tp==){
d=Query(a[i].y)-Query(a[i].x-);
if(d>=a[i].k)t1[++p1]=a[i];
else{
a[i].k-=d;
t2[++p2]=a[i];
}
}
else if(a[i].k<=l+r>>){
if(a[i].tp==)Add(a[i].x,);
if(a[i].tp==)Add(a[i].x,-);
t1[++p1]=a[i];
}
else t2[++p2]=a[i];
}
for(int i=h;i<=t;i++){
if(a[i].k<=l+r>>){
if(a[i].tp==)Add(a[i].x,-);
if(a[i].tp==)Add(a[i].x,);
}
}
for(int i=;i<=p1;i++)a[h+i-]=t1[i];
for(int i=;i<=p2;i++)a[h+i+p1-]=t2[i];
Solve(h,h+p1-,l,l+r>>);
Solve(h+p1,t,(l+r>>)+,r);
} int main(){
#ifndef ONLINE_JUDGE
freopen("dynrank.in","r",stdin);
freopen("dynrank.out","w",stdout);
#endif
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&Q);
for(int i=;i<=n;i++){
scanf("%d",&a[i].k);
a[i].x=i;a[i].tp=;
num[i]=a[i].k;
}
cntQ=;
int x,y,k;
while(Q--){
scanf("%s",op);
if(op[]=='Q'){
scanf("%d%d%d",&x,&y,&k);
a[++n].id=++cntQ;a[n].tp=;
a[n].x=x;a[n].y=y;a[n].k=k;
}
else{
scanf("%d%d",&x,&k);
a[++n].tp=;a[n].x=x;a[n].k=num[x];
a[++n].tp=;a[n].x=x;a[n].k=k;num[x]=k;
}
}
Solve(,n,,);
for(int i=;i<=cntQ;i++)
printf("%d\n",ans[i]);
}
return ;
}

高级数据结构(树状数组套主席树):ZOJ 2112 Dynamic Rankings的更多相关文章

  1. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

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

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

  3. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  4. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

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

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

  6. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

  7. [COGS257]动态排名系统 树状数组套主席树

    257. 动态排名系统 时间限制:5 s   内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...

  8. BZOJ 2141 排队(树状数组套主席树)

    解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...

  9. 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】

    题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...

  10. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

随机推荐

  1. WPF 媒体播放器(MediaElement)实例,实现进度和音量控制

    WPF 视频音频播放控件MediaElement实现进度控制,音量控制实例 说明: 1.Volume控制音量的大小,double类型,并且实现了属性依赖,可以用来双向绑定:在 0 和 1. 之间的线性 ...

  2. Windows的计划任务

    阅读目录 一:什么是Windows的计划任务? 二:如何设置计划任务 三:高级设置计划任务 一:什么是Windows的计划任务? 在日常的工作中,我们都有一些固定的或临时性的工作,而每次在爱机前一坐, ...

  3. SGU 191.Exhibition(模拟)

    时间限制:0.25s 空间限制:4M 题意: 有两个公司A.B,他们要展览物品,但是A公司的展柜要放B公司的物品,B公司的展柜要放A公司物品.最开始只有一个空柜台,从指定的一个公司开始,轮流进行操作, ...

  4. 【POJ1417】【带标记并查集+DP】True Liars

    Description After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was ...

  5. 内置方法+lambda是pythonic的利器

    python可以写的非常简洁,通过使用内置的map,reduce,filter,lambda方法,非常具有文艺范. 举个例子,例如 def fromIpToNum(ipAddr):    return ...

  6. PHP+MySQL中对UTF-8,UTF8(utf8),set names gbk 的理解

    问题一:在我们进行数据库操作时会发现,数据库中表的编码用的是utf-8,但是在进行dos命令是要使用set names gbk (一)Mysql中默认字符集设置有四级:服务器级,数据库级,表级,和字段 ...

  7. Java学习----集合框架总结

    集合框架总结: Collection接口: Set接口: HashSet//对象必须实现hashCode方法,元素没有顺序呢,效率比LinkedHashSet高 LinkedHashSet//是Has ...

  8. 极简主义,对逻辑操作符||和&&深度运用的理解

    丧心病狂的代码压缩好像违背了愉快阅读的本真,所以刨根问底想要了解个究竟,最后发现这不只是前端大牛装逼卖萌的绝技,也是代码洁癖爱好者的利器,毕竟这样看上去确实蛮优雅的; 一开始,我们接触到的代码是这样的 ...

  9. win7访问windows server 2003服务器出现未知的用户名或者错误的密码(转载)

    直接放答案,感谢网友提供答案,否则自已还一直在纳闷,为什么? win7系统的安全机制限制了登陆.只要系统时间和win2003服务器的系统时间相差很多,系统就会阻止其登陆,并显示错误信息:"未 ...

  10. 简单的html5 File base64 图片上传

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