主席树初探--BZOJ1901: Zju2112 Dynamic Rankings
n<=10000的序列做m<=10000个操作:单点修改,查区间第k小。
所谓的主席树也就是一个值域线段树嘛。。不过在这里还是%%fotile
需要做一个区间查询,由于查第k小,需要一些能够支持数值操作的东西,那就选择值域线段树,线段树上每个区间[L,R]表示的是值在L~R的数的相关信息,比如这里的“有多少个”。
不过呢这样的线段树没法维护区间下标怎么求区间信息啊,那就BIT套线段树,BIT上每个点表示一段区间(lowbit)的数值之和。为了空间,先离散化再动态开点效果拔群。
然后单点修改就该logn棵线段树,区间查询[L,R]就把R和L-1两个前缀的信息来相减。
这里第一次写树套树,见识了一种好操作!因为要同时操作很多棵线段树并且要在里面走来走去,就开一些指针一起走。那怎么知道谁要走呢?每次要区间查询时先init一下,把设计的线段树标记出来。由于两个前缀相减可能会有一些树标记到两次,那在前缀相减完之后这些标记两次的相当于不用算了,所以就把他们标记清除即可。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
//#include<iostream>
using namespace std; int n,m;
#define maxn 20011
#define maxm 4000011 struct SMT
{
struct Node
{
int son[];
int l,r;
int cnt;
}a[maxm];
int size,n;
void clear(int m) {n=m;size=;a[].cnt=;}
void up(int x) {a[x].cnt=a[a[x].son[]].cnt+a[a[x].son[]].cnt;}
void insert(int &x,int L,int R,int num)
{
if (!x) {x=++size;a[x].l=L;a[x].r=R;a[x].cnt=;}
else a[x].cnt++;
if (L==R) return;
const int mid=(L+R)>>;
if (num<=mid) insert(a[x].son[],L,mid,num);
else insert(a[x].son[],mid+,R,num);
}
void insert(int &x,int num) {insert(x,,n,num);}
void Delete(int &x,int L,int R,int num)
{
a[x].cnt--;
if (!a[x].cnt) {x=;return;}
if (L==R) return;
const int mid=(L+R)>>;
if (num<=mid) Delete(a[x].son[],L,mid,num);
else Delete(a[x].son[],mid+,R,num);
}
void Delete(int &x,int num) {Delete(x,,n,num);}
}smt;
struct BIT
{
int a[maxn],t[maxn],n;
int vis[maxn];
void clear(int m) {n=m;memset(a,,sizeof(a));memset(vis,,sizeof(vis));}
void add(int x,int num) {for (;x<=n;x+=x&-x) smt.insert(a[x],num);}
void minus(int x,int num) {for (;x<=n;x+=x&-x) smt.Delete(a[x],num);}
void init(int x,int Time)
{for (;x;x-=x&-x) if (vis[x]!=Time) vis[x]=Time,t[x]=a[x];else vis[x]=;}
int query(int x,int Time)
{int ans=;for (;x;x-=x&-x) if (vis[x]==Time) ans+=smt.a[smt.a[t[x]].son[]].cnt;return ans;}
void turn(int x,int Time,int dir) {for (;x;x-=x&-x) if (vis[x]==Time) t[x]=smt.a[t[x]].son[dir];}
}t; struct Doo
{
bool type;int x,y,z;
}doo[maxn];
int lisan[maxn],a[maxn],li=;
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]),lisan[++li]=a[i];
for (int i=;i<=m;i++)
{
char c=' ';while (c!='Q' && c!='C') c=getchar();
if ((doo[i].type=(c=='Q'))) scanf("%d%d%d",&doo[i].x,&doo[i].y,&doo[i].z);
else scanf("%d%d",&doo[i].x,&doo[i].y),lisan[++li]=doo[i].y;
}
sort(lisan+,lisan++li);li=unique(lisan+,lisan++li)-lisan-;
for (int i=;i<=n;i++) a[i]=lower_bound(lisan+,lisan++li,a[i])-lisan;
for (int i=;i<=m;i++) if (!doo[i].type) doo[i].y=lower_bound(lisan+,lisan++li,doo[i].y)-lisan; t.clear(n);smt.clear(li);
for (int i=;i<=n;i++) t.add(i,a[i]);
for (int i=;i<=m;i++)
{
if (doo[i].type)
{
int x=doo[i].x-,y=doo[i].y,z=doo[i].z,l=,r=li,tmp;
t.init(y,i);t.init(x,i);
while (l<r)
{
if ((tmp=t.query(y,i)-t.query(x,i))>=z) r=(l+r)>>,t.turn(y,i,),t.turn(x,i,);
else l=((l+r)>>)+,z-=tmp,t.turn(y,i,),t.turn(x,i,);
}
printf("%d\n",lisan[l]);
}
else
{
t.minus(doo[i].x,a[doo[i].x]);
t.add(doo[i].x,(a[doo[i].x]=doo[i].y));
}
}
return ;
}
主席树初探--BZOJ1901: Zju2112 Dynamic Rankings的更多相关文章
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- [BZOJ1901]Zju2112 Dynamic Rankings
[BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...
- BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6058 Solved: 2521 [Su ...
- BZOJ1901 Zju2112 Dynamic Rankings 主席树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1901 题意概括 给你一段序列(n个数),让你支持一些操作(共m次), 有两种操作,一种是询问区间第 ...
- [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】
题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...
- bzoj1901: Zju2112 Dynamic Rankings(BIT套主席树)
带修改的题主席树不记录前缀,只记录单点,用BIT统计前缀. 对于BIT上每一个点建一棵主席树,修改和询问的时候用BIT跑,在主席树上做就行了. 3k4人AC的题#256...应该不算慢 #incl ...
- BZOJ1901 Zju2112 Dynamic Rankings 【树状数组套主席树】
题目 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k≤j- ...
- 高级数据结构(树状数组套主席树):ZOJ 2112 Dynamic Rankings
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- BZOJ1901——Zju2112 Dynamic Rankings
1.题目大意:区间第k小,有单点修改 2.分析:这个是树状数组套线段树,也是主席树....为什么主席树这么多QAQ 就是树套树的那种插入什么的,注意啊,一定要动态开内存..不然会爆.. 然后算答案有两 ...
随机推荐
- 配置Oracle监听器
Oracle的监听和网络服务都可以在Net Manager中配置,如下图.也可以在上面的那个Net Configuration Assistant中配置,只是Net Manager比较方便些. Ora ...
- Nginx server_name 正则泛域名反向代理两例
最近在学习Nginx搭建负载均衡系统,感觉系统部署方式的思路瞬间开阔了很多. 负载均衡服务器的后端服务器上各自有一套功能相同的WEB管理系统,主要作用是方便的对各自服务器的IIS站点及服务器防火墙测量 ...
- SDK manager.exe 运行时报错:系统找不到指定的文件 android.bat
android studio 2.3.1的 SDK Manager工具 突然没有 Launcher XXX 那个按钮,只好到SDK目录中去启动,无奈发生以下错误. 解决办法:运行android.bat ...
- eclipse debug java 源码
当我们需要研究java SE的时候,debug 源码是个不错的选择,可以帮助我们清楚了解java 封装jar包的具体实现. 因为oracle 提供的源码jar包为了节省空间,所以没有将调试信息一起打包 ...
- 用 dojo/request/script 玩垮域
dojo/request/script 可以用于向服务器发送跨域请求,如JSONP等.但单看官方文档有点不容易理解,特将体会记录. require(["dojo/request/script ...
- [Windows Server 2012] 阿里云镜像购买和使用方法
★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将演示:阿里云镜像购买 ...
- Bootstrap modal使用及点击外部不消失的解决方法
这篇文章主要为大家详细介绍了Bootstrap modal使用及点击外部不消失的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了Bootstrap modal使用及点击 ...
- python_MachineLearning_感知机PLA
感知机:线性二类分类器(linear binary classifier) 感知机(perceptron)是二类分类的线性模型,其输入为实例的特征向量,输出为实例的类别,取+1和-1二值.感知机对 ...
- python3安装opencv及电子书籍(百度云)
不能直接 pip install opencv 正解: pip install opencv-python 记得:请确保网络良好!!!!! (1)这个是我学习的电子书籍:opencv-python ...
- 两个自动配置IPv4
今天一早过来发现网络连接不上了,ipconfig一下后,发现ip并不是我固定配置的ip地址,而是变成了一个完全不一样的ip,点击本地连接,点击详细信息,发现有两个自动配置IPv4,原因可能是ip地址冲 ...