zoj2112 Dynamic Rankings (主席树 || 树套树)
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
题意:给你一个长为n的区间,有m个询问和修改,每次把下标i对应的值改变,或者询问某段区间的第k小值。
思路:这题是很经典的题,可以用主席树和树套树做,对于树套树的做法,我是用线段树的每一个节点都存一个treap,然后每一次修改就是单点更新,修改的时间复杂度为O(n*logn*logn),询问时,需要二分值val,并统计线段树中对应的区间小于val值的个数,询问的时间复杂度为O(n*logn*logn*logn),所以总的时间复杂度为O(n*logn*logn*logn),同时因为线段树最多有logn层,每层都是n个节点,所以treap的空间复杂度为O(n*logn).
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 50005
int rt[maxn*4],a[maxn],n;
int cnt;
struct Treap{
int key,pri,siz,num,son[2];
void newnode(int x,int y){
key=x;pri=y;
siz=num=1;
son[0]=son[1]=0;
}
}T[20*maxn];
void rotate(int p,int &x)
{
int y=T[x].son[!p];
T[x].siz=T[x].siz-T[y].siz+T[T[y].son[p] ].siz;
T[x].son[!p]=T[y].son[p];
T[y].siz=T[y].siz-T[T[y].son[p] ].siz+T[x].siz;
T[y].son[p]=x;
x=y;
}
void charu(int key,int &x)
{
if(x==0){
x=++cnt;
T[x].newnode(key,rand());
}
else{
T[x].siz++;
if(T[x].key==key){
T[x].num++;return;
}
int p=key<T[x].key;
charu(key,T[x].son[!p]);
if(T[x].pri<T[T[x].son[!p] ].pri )
rotate(p,x);
}
}
void del(int key, int &x)
{
if(T[x].key == key)
{
if(T[x].num>1){
T[x].siz--;
T[x].num--;
return;
}
if(T[x].son[0] && T[x].son[1])
{
int p=T[T[x].son[0]].pri>T[T[x].son[1]].pri;
rotate(p,x);
del(key,x);
}
else x=T[x].son[1]+T[x].son[0];
}
else
{
T[x].siz--;
int p=T[x].key>key;
del(key,T[x].son[!p]);
}
}
int query_rank(int key,int &x)
{
if(x==0)return 0;
if(T[x].key==key)return T[T[x].son[0] ].siz;
if(T[x].key>key)return query_rank(key,T[x].son[0]);
if(T[x].key<key)return T[T[x].son[0] ].siz+T[x].num+query_rank(key,T[x].son[1]);
}
void update(int idx,int val,int L,int R,int th,int f)
{
if(f)del(a[idx],rt[th]);
charu(val,rt[th]);
if(L==idx && R==idx){
a[idx]=val;
return;
}
int mid=(L+R)/2;
if(idx<=mid)update(idx,val,L,mid,lson,f);
else update(idx,val,mid+1,R,rson,f);
}
int question(int l,int r,int val,int L,int R,int th)
{
int mid;
if(l==L && r==R){
return query_rank(val,rt[th]);
}
mid=(L+R)/2;
if(r<=mid)return question(l,r,val,L,mid,lson);
else if(l>mid)return question(l,r,val,mid+1,R,rson);
else return question(l,mid,val,L,mid,lson)+question(mid+1,r,val,mid+1,R,rson);
}
int main()
{
int m,i,j,Tcase,l,r,c,d,e,mid;
char s[10];
scanf("%d",&Tcase);
while(Tcase--)
{
memset(rt,0,sizeof(rt));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
cnt=0;
for(i=1;i<=n;i++){
update(i,a[i],1,n,1,0);
}
for(i=1;i<=m;i++){
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d",&c,&d);
update(c,d,1,n,1,1);
}
else{
scanf("%d%d%d",&c,&d,&e);
l=0;r=1000000000;
while(l<=r){
mid=(l+r)/2;
//printf("%d %d %d\n",l,r,mid);
if(question(c,d,mid,1,n,1)>=e)r=mid-1;
else l=mid+1;
}
printf("%d\n",r);
}
}
}
return 0;
}
/*
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
*/
主席树做法:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define lth th<<1
#define rth th<<1|1
#define inf 99999999
#define pi acos(-1.0)
#define maxn 60005
#define M 2500010
int a[maxn],n;
struct node{
int l,r,kind,d;
}ques[10005];
int pos[maxn],T[maxn],S[maxn];
int lson[M],rson[M],c[M];
int th,tot;
int build(int l,int r)
{
int newroot=++th,i,j,mid;
c[newroot]=0; //!!!
if(l!=r){
mid=(l+r)/2;
lson[newroot]=build(l,mid);
rson[newroot]=build(mid+1,r);
}
return newroot;
}
int update(int root,int zhi,int value)
{
int i,j;
int newroot=++th;int tmp=newroot;
int l=1,r=tot,mid;
c[newroot]=c[root]+value;
while(l<r){
mid=(l+r)/2;
if(zhi<=mid){
r=mid;
lson[newroot ]=++th;rson[newroot]=rson[root];
newroot=lson[newroot];root=lson[root];
}
else{
l=mid+1;
lson[newroot ]=lson[root];rson[newroot]=++th;
newroot=rson[newroot];root=rson[root];
}
c[newroot]=c[root]+value;
}
return tmp;
}
int lowbit(int x)
{
return x&(-x);
}
void modify(int pos,int zhi,int value)
{
int i,j;
while(pos<=n){
S[pos]=update(S[pos],zhi,value);
pos+=lowbit(pos);
}
}
int use[maxn];
int getsum(int pos)
{
int sum=0;
while(pos>0){
sum+=c[lson[use[pos] ] ];
pos-=lowbit(pos);
}
return sum;
}
int question(int left,int right,int k)
{
int i,j,root1,root2;
int l=1,r=tot,mid;
for(i=left-1;i>0;i-=lowbit(i))use[i]=S[i];
for(i=right;i>0;i-=lowbit(i))use[i]=S[i];
root1=T[left-1];root2=T[right];
while(l<r){
mid=(l+r)/2;
int tmp=getsum(right)-getsum(left-1)+c[lson[root2] ]-c[lson[root1] ];
if(tmp>=k){
r=mid;
root1=lson[root1];root2=lson[root2];
for(i=left-1;i>0;i-=lowbit(i))use[i]=lson[use[i] ];
for(i=right;i>0;i-=lowbit(i))use[i]=lson[use[i] ];
}
else{
k-=tmp;
l=mid+1;
root1=rson[root1];root2=rson[root2];
for(i=left-1;i>0;i-=lowbit(i))use[i]=rson[use[i] ];
for(i=right;i>0;i-=lowbit(i))use[i]=rson[use[i] ];
}
}
return l;
}
int main()
{
int m,i,j,Tcase,c,d,e;
char str[5];
scanf("%d",&Tcase);
while(Tcase--)
{
scanf("%d%d",&n,&m);
tot=0;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
tot++;
pos[tot]=a[i];
}
for(i=1;i<=m;i++){
scanf("%s",str);
if(str[0]=='Q'){
scanf("%d%d%d",&c,&d,&e);
ques[i].kind=0;ques[i].l=c;ques[i].r=d;ques[i].d=e;
}
else if(str[0]=='C'){
scanf("%d%d",&c,&d);
tot++;pos[tot]=d;
ques[i].kind=1;ques[i].l=c;ques[i].r=d;
}
}
sort(pos+1,pos+1+tot);
tot=unique(pos+1,pos+1+tot)-pos-1;
th=0;
T[0]=build(1,tot);
for(i=1;i<=n;i++){
int t=lower_bound(pos+1,pos+1+tot,a[i])-pos;
T[i]=update(T[i-1],t,1);
}
for(i=1;i<=n;i++){
S[i]=T[0];
}
for(i=1;i<=m;i++){
if(ques[i].kind==0){ //表示询问
printf("%d\n",pos[question(ques[i].l,ques[i].r,ques[i].d)]);
}
else{
int t1=lower_bound(pos+1,pos+1+tot,a[ques[i].l])-pos;
int t2=lower_bound(pos+1,pos+1+tot,ques[i].r)-pos;
modify(ques[i].l,t1,-1);
modify(ques[i].l,t2,1);
a[ques[i].l ]=ques[i].r; //!!!
}
}
}
return 0;
}
/*
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
*/
zoj2112 Dynamic Rankings (主席树 || 树套树)的更多相关文章
- ZOJ2112 Dynamic Rankings (线段树套平衡树)(主席树)
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- Bzoj 1901: Zju2112 Dynamic Rankings 主席树,可持久,树状数组,离散化
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6321 Solved: 2628[Su ...
- 【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组
[BZOJ1901]Zju2112 Dynamic Rankings Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j ...
- 洛谷P2617 Dynamic Rankings (主席树)
洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...
- zoj 2112 Dynamic Rankings(主席树&动态第k大)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...
- ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大
Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...
- ZOJ2112 Dynamic Rankings(整体二分)
今天学习了一个奇技淫巧--整体二分.关于整体二分的一些理论性的东西,可以参见XRH的<浅谈数据结构题的几个非经典解法>.然后下面是一些个人的心得体会吧,写下来希望加深一下自己的理解,或者如 ...
随机推荐
- 【C++】《Effective C++》第一章
第一章 让自己习惯C++ C++是一个威力强大的语言,带着众多特性,但是在你可以驾驭其威力并有效运用其特性之前,你必须先习惯C++的办事方式. 条款01:视C++为一个语言联邦 如今的C++已经是个多 ...
- SpringBoot对静态资源的映射规则
在WebMvcAutoConfiguration类中有相对应的方法addResourceHandlers public void addResourceHandlers(ResourceHandler ...
- jenkins 构建历史 显示版本号
0 jenkins 安装此插件: 此插件名为 " groovy postbuild " 1 效果图: 2 安装插件: 系统管理 --> 插件管理 --> 可选 ...
- CVE-2019-15107_webmin漏洞复现
一.漏洞描述 Webmin的是一个用于管理类Unix的系统的管理配置工具,具有网络页面.在其找回密码页面中,存在一处无需权限的命令注入漏洞,通过这个漏洞攻击者即可以执行任意系统命令.它已知在端口100 ...
- Canal:同步mysql增量数据工具,一篇详解核心知识点
老刘是一名即将找工作的研二学生,写博客一方面是总结大数据开发的知识点,一方面是希望能够帮助伙伴让自学从此不求人.由于老刘是自学大数据开发,博客中肯定会存在一些不足,还希望大家能够批评指正,让我们一起进 ...
- 5V 升压 8.4V,5V 转 8.4V 做两节锂电池充电芯片
5V 升压 8.4V SOT23-6 封装的六脚升压 IC PW5300 是一颗 DC-DC 异步整流升压转换器芯片,输入电压范围 2.6V-5.5V.最高输出 电压 12V, PW5300 是一种电 ...
- 2V升5V的升压芯片,两款芯片电路图
2V的输入电压,是可以用来做5V输出的升压电路,但是2V的供电设备很少,不知道还有什么东西是2V电压的,还需要升压到5V的电路系统. 两款2V升5V的芯片电路图: 第1, PW5100升压芯片,输出电 ...
- 获取网页url中的参数
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- pytorch——预测值转换为概率,单层感知机
softmax函数,可以将算出来的预测值转换成0-1之间的概率形式 导数的形式 import torch import torch.nn.functional as F x=torch.tensor( ...
- css animation @keyframes 动画
需求:语音播放动态效果 方案:使用如下图片,利用 css animation @keyframes 做动画 html <span class="horn" :class=& ...