Bzoj 1901: Zju2112 Dynamic Rankings 树套树,线段树,平衡树,Treap
2016-03-30 11:33
453 查看
1901: Zju2112 Dynamic Rankings
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6471 Solved: 2697
[Submit][Status][Discuss]
Description
给定一个含有n个数的序列a[1],a[2],a[3]……a,程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a
,这些数都小于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。
Input
对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。Output
Sample Input
5 33 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
36
HINT
20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。Source
区间线段树套Treap上次写了个树状数组套主席树,这次复习一下区间线段树套Treap。
就是在询问时,去二分答案,然后判定小于等于二分的答案的个数是否有K个即可。
#include<bits/stdc++.h> using namespace std; #define MAXN 10010 struct node { int left,right,val,size,rnd,count; }tree[MAXN*300]; int tmp,SIZE,root[MAXN*300],a[MAXN]; int read() { int s=0,fh=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();} while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();} return s*fh; } void Update(int k){tree[k].size=tree[tree[k].left].size+tree[tree[k].right].size+tree[k].count;} void Lturn(int &k){int t=tree[k].right;tree[k].right=tree[t].left;tree[t].left=k;tree[t].size=tree[k].size;Update(k);k=t;} void Rturn(int &k){int t=tree[k].left;tree[k].left=tree[t].right;tree[t].right=k;tree[t].size=tree[k].size;Update(k);k=t;} void Insert(int &k,int x) { if(k==0) { SIZE++;k=SIZE; tree[k].val=x;tree[k].size=tree[k].count=1;tree[k].rnd=rand(); return; } tree[k].size++; if(x==tree[k].val){tree[k].count++;return;} if(x<tree[k].val){Insert(tree[k].left,x);if(tree[tree[k].left].rnd<tree[k].rnd)Rturn(k);} else {Insert(tree[k].right,x);if(tree[tree[k].right].rnd<tree[k].rnd)Lturn(k);} } void Del(int &k,int x) { if(k==0)return; if(tree[k].val==x) { if(tree[k].count>1){tree[k].size--;tree[k].count--;return;} if(tree[k].left*tree[k].right==0)k=tree[k].left+tree[k].right; else if(tree[tree[k].left].rnd<tree[tree[k].right].rnd){Rturn(k);Del(k,x);} else {Lturn(k);Del(k,x);} } else if(x<tree[k].val){tree[k].size--;Del(tree[k].left,x);} else {tree[k].size--;Del(tree[k].right,x);} } void Find(int k,int x) { if(k==0)return; if(tree[k].val<=x){tmp+=(tree[tree[k].left].size+tree[k].count);Find(tree[k].right,x);} else Find(tree[k].left,x); } void Build(int k,int l,int r,int lr,int B) { Insert(root[k],B); if(l==r)return; int mid=(l+r)/2; if(lr<=mid)Build(k*2,l,mid,lr,B); else Build(k*2+1,mid+1,r,lr,B); } void Query(int k,int l,int r,int ql,int qr,int Q) { if(l==ql&&r==qr){Find(root[k],Q);return;} int mid=(l+r)/2; if(qr<=mid)Query(k*2,l,mid,ql,qr,Q); else if(ql>mid)Query(k*2+1,mid+1,r,ql,qr,Q); else {Query(k*2,l,mid,ql,mid,Q);Query(k*2+1,mid+1,r,mid+1,qr,Q);} } void Change(int k,int l,int r,int lr,int C1,int C2) { Del(root[k],C1); Insert(root[k],C2); if(l==r)return; int mid=(l+r)/2; if(lr<=mid)Change(k*2,l,mid,lr,C1,C2); else Change(k*2+1,mid+1,r,lr,C1,C2); } int main() { int n,m,i,l,r,k,L,R,mid,ii,ans; char zs; n=read();m=read(); for(i=1;i<=n;i++)a[i]=read(); for(i=1;i<=n;i++)Build(1,1,n,i,a[i]); for(i=1;i<=m;i++) { scanf("\n%c",&zs); if(zs=='Q') { l=read();r=read();k=read(); L=0;R=1000000000;ans=0; while(L<=R) { mid=(L+R)/2; tmp=0; Query(1,1,n,l,r,mid); if(tmp<k)L=mid+1; else {ans=mid;R=mid-1;} //else {ans=mid;break;} //if(tmp>=k)R=mid-1; //else L=mid+1; } //printf("%d\n",L); printf("%d\n",ans); } else { ii=read();k=read(); Change(1,1,n,ii,a[ii],k); a[ii]=k; } } fclose(stdin); fclose(stdout); return 0; }
相关文章推荐
- 单元测试
- iOS图片如何按比例显示
- viewpager 左右滑动笔记
- alert 换行
- Maven入门指南⑤:使用Nexus搭建Maven私服
- linux中安装配置nexus以及maven的安装配置
- ArcGIS与R语言的Delaunay 三角网生成法
- Servlet生命周期
- 反射原理及使用
- SVN 集中式版本控制软件
- IOS开发Swift键盘收起,键盘挡住输入模框的处理
- 通过配置文件对“安卓热敏打印的PDA手持终端”的按键分配功能
- iOS沙盒目录解析
- karaf jvm参数配置
- windows常用的命令
- Linux下php安装curl扩展
- jsp页面使用C标签对时间日期进行判断
- socket通信简介
- NSDate 时差8小时解决方法
- SQLite BEGIN TRANSACTION创建提交事务 http://www.uedsc.com/sqlite-begin-transaction.html