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.

<b< dd="">

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

第一次写树套树,而且应该是最基础的树套树,手抄大佬函数,自己整理成结构体。

没看别人题解的时候再高数课上YY,以为是对于线段树的每个节点套一个平衡树,这样的话想了一下,开的空间大概是n*lgn*n,基本上是炸了的。

但是好像没有必要每个节点建立一个Treap,每个Treap给n个节点。因为过于浪费。

大佬们好像是只建立一个大Treap,但是有n个root,然后把空间分配到小Treap里面。

但是这样空间开n*lgn*lgn,好像1000000的空间还是不够处理极限情况啊。。。不知道这么回事。

copy from qscqesze 顾学姐?结合前两天写的线段树和Treap,我们两个的风格还是比较像的,所以我理解代码起来也比较快。ORZ。。。对于空间的问题,多做几个题再回头分析。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<ctime>
using namespace std;
#define maxn 1000001
int tmp=;
struct Treap
{
int root[maxn],sz,s[maxn],ch[maxn][],v[maxn],w[maxn],rnd[maxn];//s是size,w是cnt
//rnd小根堆
void init()
{
memset(root,,sizeof(root));
sz=;
}
void Update(int now)
{
s[now]=s[ch[now][]]+s[ch[now][]]+w[now];
}
void rotate(int &now,int p)
{
int t=ch[now][p];
ch[now][p]=ch[t][-p],ch[t][-p]=now,s[t]=s[now];
Update(now);now=t;//好像明白了为什么要替代:k得到儿子信息
}
void Insert(int &now,int num)
{
if(!now){
now=++sz;s[now]=w[now]=;ch[now][]=ch[now][]=;rnd[now]=rand();
v[now]=num;return;
}
s[now]++;
if(v[now]==num)w[now]++;
else{
int t=num>v[now];
Insert(ch[now][t],num);
if(rnd[ch[now][t]]<rnd[now])
rotate(now,t);
}
}
void Del(int &now,int num)//code better than mine before
{
if(v[now]==num){
if(w[now]>){
w[now]--;
s[now]--;
return;
}
if(ch[now][]*ch[now][]==)
now=ch[now][]+ch[now][];
else rotate(now,rnd[ch[now][]]>rnd[ch[now][]]),Del(now,num);
}
else {
Del(ch[now][num>v[now]],num);
s[now]--;
}
}
void Find(int now,int num)
{
if(!now) return;
if(v[now]<=num){
tmp+=s[ch[now][]]+w[now];
Find(ch[now][],num);
}
else Find(ch[now][],num);
}
}Tr;
/////////////////////线段树
void Seg_insert(int now,int l,int r,int x,int num)
{
Tr.Insert(Tr.root[now],num);
if(l==r)return;
int mid=(l+r)>>;
if(x<=mid)Seg_insert(now<<,l,mid,x,num);
else Seg_insert(now<<|,mid+,r,x,num);
} void Seg_change(int now,int l,int r,int x,int Now,int Pre)
{
Tr.Del(Tr.root[now],Pre);
Tr.Insert(Tr.root[now],Now);
if(l==r)return;
int mid=(l+r)>>;
if(x<=mid)Seg_change(now<<,l,mid,x,Now,Pre);
else Seg_change(now<<|,mid+,r,x,Now,Pre);
}
void Seg_query(int now,int l,int r,int L,int R,int num)
{
if(l==L&&r==R)
{
Tr.Find(Tr.root[now],num);
return;
}
int mid = (l+r)>>;
if(mid>=R)
Seg_query(now<<,l,mid,L,R,num);
else if(mid<L)
Seg_query(now<<|,mid+,r,L,R,num);
else{
Seg_query(now<<,l,mid,L,mid,num);
Seg_query(now<<|,mid+,r,mid+,R,num);
}
}
///////////////////////////
int a[maxn];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
Tr.init();
int n,m;scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
Seg_insert(,,n,i,a[i]);
}
char op[];
for(int i=;i<=m;i++){
scanf("%s",op);
if(op[]=='C'){
int x,y;scanf("%d%d",&x,&y);
Seg_change(,,n,x,y,a[x]);
a[x]=y;
}
else{
int x,y,z;scanf("%d%d%d",&x,&y,&z);
int l = ,r = 1e9;
while(l<=r){
int mid = (l+r)>>;
tmp=; Seg_query(,,n,x,y,mid);
if(tmp>=z)r=mid-;
else l=mid+;
}
printf("%d\n",l);
}
}
}
return ;
}

(2700ms左右);

这题还有主席树(200ms左右)

代码见:http://www.cnblogs.com/hua-dong/p/7931778.html

ZOJ2112 Dynamic Rankings (线段树套平衡树)(主席树)的更多相关文章

  1. Dynamic Rankings—带单点修改的主席树

    这道题应该是很不错的板子了\(\mathcal{\color{cyan}{Link}}\) \(\mathcal{\color{red}{Description}}\) 给定一个序列,有两种操作.一是 ...

  2. BZOJ.1901.Dynamic Rankings(线段树套平衡树 Splay)

    题目链接or Here 题意:n个数,有两个操作:1.修改某个数为v:2.询问一段区间第k小的数 如果没有修改,则可以用线段树,每个节点P[a,b]存储大小为b-a+1的数组,代表其中的数 同时,这个 ...

  3. ZOJ - 2112 Dynamic Rankings(BIT套主席树)

    纠结了好久的一道题,以前是用线段树套平衡树二分做的,感觉时间复杂度和分块差不多了... 终于用BIT套函数式线段树了过了,120ms就是快,此题主要是卡内存. 假设离散后有ns个不同的值,递归层数是l ...

  4. 树套树Day1线段树套平衡树bzoj3196

    您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查 ...

  5. 浅谈树套树(线段树套平衡树)&学习笔记

    0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...

  6. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

  7. 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2271  Solved: 935[Submit][Stat ...

  8. CF 19D - Points 线段树套平衡树

    题目在这: 给出三种操作: 1.增加点(x,y) 2.删除点(x,y) 3.询问在点(x,y)右上方的点,如果有相同,输出最左边的,如果还有相同,输出最低的那个点 分析: 线段树套平衡树. 我们先离散 ...

  9. BZOJ3196二逼平衡树——线段树套平衡树(treap)

    此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...

  10. P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)

    P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...

随机推荐

  1. HDU 3199 Hamming Problem

    Hamming Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  2. python glob

    http://python.jobbole.com/81552/ glob模块是最简单的模块之一,内容非常少.用它可以查找符合特定规则的文件路径名.跟使用windows下的文件搜索差不多.查找文件只用 ...

  3. json教程系列(4)-optXXX方法的使用

    在JSONObject获取value有多种方法,如果key不存在的话,这些方法无一例外的都会抛出异常.如果在线环境抛出异常,就会使出现error页面,影响用户体验,针对这种情况最好是使用optXXX方 ...

  4. <script>放在head内和body内有什么区别

    加载的顺序不一样,你可以把HTML看成从上往下加载的. 例如在网速慢的情况下把js代码放在body底部用户会先看到网页结构,等js加载完成后才出现特效 区别简述: 在HTML body部分中的Java ...

  5. 虚构 css 父级选择器

    能 CSS 解决的绝不用 JS,这句话又一次故作装逼地说出来还是挺爽的... 比如下拉列表,能用 CSS 的 :focus 就不用 JS 的 .on("focus blur") 能 ...

  6. 在Java中调用Python代码

    极少数时候,我们会碰到类似这样的问题:与A同学合作写代码, A同学只会写Python,不熟悉Java ,而你只会写Java不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方 ...

  7. 0625 Django 基础

    相关命令: 1 创建项目 django-admin startproject 项目名称 2 创建应用 python manage.py startapp app名称 3 启动项目 python man ...

  8. 谷歌浏览器安装jsonview插件方法

    参考https://www.cnblogs.com/whycxb/p/7126116.html,已安装成功.

  9. Android中设置自己软件的铃声+震动

    有时候一些通讯软件需要这些个功能,比如说收到短信,通知等,要求手机发出铃声,或震动,或发光以提示用户知晓. 往往手机都是有默认设置的,比如说用户开启了铃声+震动:只铃声不震动:完全静音等等... 这个 ...

  10. 比较好的sql写法

    DECLARE @beginTime VARCHAR(20)= '2017-11-13 00:00:00';DECLARE @endTime VARCHAR(20)= '2017-11-13 23:0 ...