CRB and Queries

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1602    Accepted Submission(s): 409

Problem Description
There are N boys in CodeLand.
Boy i has his coding skill Ai.
CRB wants to know who has the suitable coding skill.
So you should treat the following two types of queries.
Query 1: 1 l v
The coding skill of Boy l has changed to v.
Query 2: 2 l r k
This is a report query which asks the k-th smallest value of coding skill between Boy l and Boy r(both inclusive).
 
Input
There are multiple test cases. 
The first line contains a single integer N.
Next line contains N space separated integers A1, A2, …, AN, where Ai denotes initial coding skill of Boy i.
Next line contains a single integer Q representing the number of queries.
Next Q lines contain queries which can be any of the two types.
1 ≤ N, Q ≤ 105
1 ≤ Ai, v ≤ 109
1 ≤ l ≤ r ≤ N
1 ≤ k ≤ r – l + 1

 
Output
For each query of type 2, output a single integer corresponding to the answer in a single line.
 
Sample Input
5
1 2 3 4 5
3
2 2 4 2
1 3 6
2 2 4 2
 
Sample Output
3
4
 
Author
KUT(DPRK)
 
Source
 

题目大意:给你一个数列有n个数,q次询问。询问1可以把某个位置改为值b。询问2然后问L - R之间第k大的数是多少。简单来说,就是带修改的动态区间第k大问题。

解题思路:用线段树维护Ci在去重后的所有可能出现在数列中的数当中的大小排名,用Treap维护Ci在数列中的位置关系。其实我觉得这才是内涵。然后对于查询区间L - R的第k大。那么如果在线段树左儿子代表的Treap树中在R位置之前的个数减去左儿子代表的Treap树中的(L-1)之前的个数大于k,那么就可以在左儿子中找位置。

#include<stdio.h>
#include<string.h>
#include<time.h>
#include<algorithm>
using namespace std;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int maxn=1e6;
struct Treap{
int rk;
int coun;
int sz;
int v;
Treap *ch[2];
Treap() {
coun=0;
sz=0;
rk=-maxn; //
v=0;
}
int cmp(int x) const {
if(x==v){
return -1;
}
return x<v ? 0:1;
}
};
Treap *seg[maxn*8];
Treap *null;
int oper[maxn][4];
int a[maxn],b[maxn*3];
int discr(int l,int r,int key){
while(l<=r){
int md=(l+r)/2;
if(key<b[md]){
r=md-1;
}else if(key > b[md]){
l=md+1;
}else{
return md;
}
}
return -1;
}
void update(Treap * &o){
o->sz = o->ch[0]->sz + o->coun + o->ch[1]->sz;
}
void rotate(Treap * &o,int d){
Treap *k=o->ch[d^1]; o->ch[d^1]= k->ch[d]; k->ch[d]=o;
update(o); update(k); o=k;
}
void insert_tp(Treap * &o,int x){
if(o==null){
o = new Treap();
o->ch[0]=o->ch[1]=null;
o->v = x; o->coun = 1; o->rk = rand();
}else{
int d=o->cmp(x);
insert_tp(o->ch[d],x);
if(o->ch[d]->rk > o->rk) rotate(o,d^1);
}
update(o);
}
void insert_seg(int rt,int L,int R,int pos,int x){
insert_tp(seg[rt],x);
if(L==R)
return ;
if(pos<=mid){
insert_seg(lson,pos,x);
}else{
insert_seg(rson,pos,x);
}
}
void free_tp(Treap *&o){
if(o->ch[0]==null&&o->ch[1]==null){
free(o);
return ;
}
if(o->ch[0]!=null){
free_tp(o->ch[0]);
}
if(o->ch[1]!=null){
free_tp(o->ch[1]);
}
free(o);
}
void clean(int rt,int L,int R){
if(L==R){
free_tp(seg[rt]);
return ;
}
clean(lson);
clean(rson);
free_tp(seg[rt]);
}
void del_tp(Treap * &o,int x){
int d=o->cmp(x);
if(d==-1){
if(o->ch[0]==null&&o->ch[1]==null){ //
Treap *pt=o;
o = null;
free(pt);
}
else if(o->ch[0]==null){
Treap *pt=o;
o=o->ch[1];
free(pt);
}else if(o->ch[1]==null){
Treap *pt=o;
o= o->ch[0];
free(pt);
}else{
int d2=( o->ch[0]->rk >o->ch[1]->rk ? 1:0 );
rotate(o,d2);
del_tp(o->ch[d2],x);
}
}else{
del_tp(o->ch[d],x);
}
update(o);
}
void del_seg(int rt,int L,int R,int pos,int x){
del_tp(seg[rt],x);
if(L==R)
return ;
if(pos<=mid){
del_seg(lson,pos,x);
}else{
del_seg(rson,pos,x);
}
}
int select(Treap *o,int x){
if(o==null){
return 0;
}
if(o->v > x) return select(o->ch[0],x);
return o->ch[0]->sz + o->coun +select(o->ch[1],x);
}
int query(int rt,int L,int R,int x,int y,int k){
if(L==R) return L;
int ans=select(seg[rt*2],y)-select(seg[rt*2],x);
if(ans>=k)
return query(lson,x,y,k);
else return query(rson,x,y,k-ans);
}
void init(){
null =new Treap();
null->ch[0]=null->ch[1]=null;
null->sz = null->coun=0;
for(int i=0;i<=maxn*4-1;i++){
seg[i] = null;
}
}
int main(){
// freopen("1007.in","r",stdin);
// freopen("OUT.txt","w",stdout);
int n,Q,typ,x,y,z,nn,mm;
while(scanf("%d",&n)!=EOF){
init();
mm=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
b[mm++]=a[i];
}
scanf("%d",&Q);
for(int i=0;i<Q;i++){
scanf("%d",&typ);
oper[i][0]=typ;
if(typ==2){
scanf("%d%d%d",&x,&y,&z);
oper[i][1]=x;
oper[i][2]=y;
oper[i][3]=z;
}else{
scanf("%d%d",&x,&z);
oper[i][1]=x;
oper[i][2]=z;
b[mm++]=z;
}
}
sort(b,b+mm);
nn=1;
for(int i=1;i<mm;i++){
if(b[i]!=b[i-1]){
b[nn++]=b[i];
}
}
for(int i=0;i<n;i++){
a[i]= discr(0,nn-1,a[i])+1;
insert_seg(1,1,nn,a[i],i+1);
}
for(int i=0;i<Q;i++){
if(oper[i][0]==1){
int kk=0;
del_seg(1,1,nn,a[oper[i][1]-1],oper[i][1]);
kk=discr(0,nn-1,oper[i][2]);
a[oper[i][1]-1]=kk+1;
insert_seg(1,1,nn,a[oper[i][1]-1],oper[i][1]);
}else{
int tmp=query(1,1,nn,oper[i][1]-1,oper[i][2],oper[i][3])-1;
printf("%d\n",b[tmp]);
}
}
clean(1,1,nn);
}
return 0;
} /* 5
1 1 1 1 1
10
1 2 3
2 1 4 3
1 5 6
1 4 2
1 5 3
2 1 3 3
2 1 4 4
2 2 5 2
2 2 5 3
2 2 5 4 */

  

HDU 5412——CRB and Queries——————【线段树套Treap(并没有AC)】的更多相关文章

  1. HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5412 Problem Description There are N boys in CodeLan ...

  2. BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】

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

  3. BZOJ - 3196 Tyvj 1730 二逼平衡树 (线段树套treap)

    题目链接 区间线段树套treap,空间复杂度$O(nlogn)$,时间复杂度除了查询区间k大是$O(log^3n)$以外都是$O(log^2n)$的. (据说线段树套线段树.树状数组套线段树也能过?) ...

  4. 初学树套树:线段树套Treap

    前言 树套树是一个十分神奇的算法,种类也有很多:像什么树状数组套主席树.树状数组套值域线段树.\(zkw\)线段树套\(vector\)等等. 不过,像我这么弱,当然只会最经典的 线段树套\(Trea ...

  5. BZOJ2141&洛谷1975 排队 【线段树套treap】

    题目 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别,排 ...

  6. hdu 5412 CRB and Queries

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5412 CRB and Queries Description There are $N$ boys i ...

  7. bzoj 3196 && luogu 3380 JoyOI 1730 二逼平衡树 (线段树套Treap)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 题面; 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Se ...

  8. 【bzoj3196】Tyvj 1730 二逼平衡树 线段树套Treap

    题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义 ...

  9. bzoj3196 二逼平衡树 树套树(线段树套Treap)

    Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4697  Solved: 1798[Submit][Status][D ...

随机推荐

  1. C#泛型理解(一)

    一.什么是泛型 泛型是C#语言和公共语言运行库(CLR)中的一个新功能,它将类型参数的概念引入.NET Framework.类型参数使得设计某些类和方法成为可能,例如,通过使用泛型类型参数T,可以大大 ...

  2. symbol访问法及symbor注册表

    symbol主要作用是防止对象属性名冲突 在ES6之前,对象的属性名只能是字符串,这样很容易造成字符串的冲突. 例:假设person对象是从外部库引入的一个对象 let person = { name ...

  3. ubuntu - 14.04,该如何分区安装(初学者或不用它作为生成环境使用)?

    ubuntu14.04,实际上现在它的安装很简单了,全图形界面,可以选择母语,但是实际使用起来如果分区不当,会让我们付出惨痛的代价,那么我们应该怎么分区安装呢? 如果我们并不是把它作为专业的服务器,或 ...

  4. yum(Fedora和RedHat以及SUSE中的Shell前端软件包管理器)命令详解

    yum官方网站:http://yum.baseurl.org/ Fedora对于yum的介绍:http://fedoraproject.org/wiki/Yum yum(全称为 Yellow dog ...

  5. Kafka学习文档

    本教程假定您是一只小白,没有Kafka 或ZooKeeper 方面的经验. Kafka脚本在Unix和Windows平台有所不同,在Windows平台,请使用 bin\windows\ 而不是bin/ ...

  6. 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人

    P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...

  7. SSKeychain的使用 钥匙串

    一.首先要理解keychain与userdefaults的区别: 1.keychain是将数据加密后存储在本地,更安全.路径:Library/Application Support/iPhone Si ...

  8. vs已停止工作的解决方案

    解决办法 第一步: 开始-->所有程序-->Microsoft Visual Studio 2013(2015)-->VisualStudio Tools-->VS2013(2 ...

  9. [Ruby]转载: 关于ruby中 %Q, %q, %W, %w, %x, %r, %s 的用法

    单引号内的内容,ruby会原样输出 双引号内的内容,ruby会解析 我们看个简单的例子,针对字符串      #{foo}test     我们分别用单引号核双引号操作 '#{foo}test'   ...

  10. day25 网络编程之socket sc架构

    1.  为什么要学习socket? socket就是网络通信的工具,任何一门语言都有socket,他不是任何一个语言的专有名词,而是大家通过自己的程序与其他电脑进行网络通信的时候都用它. 2.  客户 ...