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. Educational Codeforces Round 29(6/7)

    1.Quasi-palindrome 题意:问一个字符串(你可以添加前导‘0’或不添加)是否是回文串 思路:将给定的字符串的前缀‘0’和后缀‘0’都去掉,然后看其是否为回文串 #include< ...

  2. XP、win7下Excel 2007多窗口打开Excel的解决方法

    http://blog.x6x8.com/?p=330 Win7下的方法(借鉴了XP的方法): 1.先在桌面先建一个txt文件,将下面的代码复制进去 32位WIN7复制下面一行start “Excel ...

  3. paramiko 模块安装和使用

    一.Centos安装Paramiko 1.安装组件 yum install openssl openssl-devel python-dev pycrypto -y yum install zlib- ...

  4. Linux CentOS7安装Mysql5.7

    一.下载mysql mkdir /home/install #创建install目录 在/home/install目录下下载mysql5.7 wget https://cdn.mysql.com//D ...

  5. 一、安装虚拟机,配置ip地址

    一.安装linux 注意点: 一.选择最小化安装的时候,要自定义安装软件,必须要安装下面的 如果没有安装上面的,需要用下面的命令来查询安装 如果没有安装就会出现各种问题 二.分区简单介绍 1.至少要一 ...

  6. python实现免密码登录lunx服务器

    import paramikoimport oshostname='192.168.76.10'username='root'# password='123456'ssh=paramiko.SSHCl ...

  7. 報錯:One or more validation errors were detected during model generation:System.Data.Edm.EdmEntityType: : EntityType 'Movie' has no key

    報錯:One or more validation errors were detected during model generation:System.Data.Edm.EdmEntityType ...

  8. 几招教会你解决网站出现DNS域名解析错误的困扰!

    DNS解析就是把你的域名解析成一个ip地址,服务商提供的dns解析就是能够将你的域名解析成相应ip地址的主机.这就是DNS域名解析. DNS解析出现错误,一般是我们把一个域名解析成一个错误的IP地址, ...

  9. PAT1058. A+B in Hogwarts (20)

    #include <iostream> using namespace std; int ag,as,ak; int bg,bs,bk; int cg,cs,ck; int main(){ ...

  10. Eclipse导出apk

    http://jingyan.baidu.com/article/7908e85c8dea30af491ad24f.html