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的更多相关文章

  1. 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings

    谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...

  2. [BZOJ1901]Zju2112 Dynamic Rankings

    [BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...

  3. BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6058 Solved: 2521 [Su ...

  4. BZOJ1901 Zju2112 Dynamic Rankings 主席树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1901 题意概括 给你一段序列(n个数),让你支持一些操作(共m次), 有两种操作,一种是询问区间第 ...

  5. [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】

    题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...

  6. bzoj1901: Zju2112 Dynamic Rankings(BIT套主席树)

    带修改的题主席树不记录前缀,只记录单点,用BIT统计前缀.  对于BIT上每一个点建一棵主席树,修改和询问的时候用BIT跑,在主席树上做就行了.  3k4人AC的题#256...应该不算慢 #incl ...

  7. 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- ...

  8. 高级数据结构(树状数组套主席树):ZOJ 2112 Dynamic Rankings

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  9. BZOJ1901——Zju2112 Dynamic Rankings

    1.题目大意:区间第k小,有单点修改 2.分析:这个是树状数组套线段树,也是主席树....为什么主席树这么多QAQ 就是树套树的那种插入什么的,注意啊,一定要动态开内存..不然会爆.. 然后算答案有两 ...

随机推荐

  1. 前端组件化(二):优化 DOM 操作

    看看上一节我们的代码,仔细留意一下 changeLikeText 函数,这个函数包含了 DOM 操作,现在看起来比较简单,那是因为现在只有 isLiked 一个状态.由于数据状态改变会导致需要我们去更 ...

  2. 掌握Spark机器学习库-07-回归算法原理

    1)机器学习模型理解 统计学习,神经网络 2)预测结果的衡量 代价函数(cost function).损失函数(loss function) 3)线性回归是监督学习

  3. SQL Server xtype的介绍

    sysobjects 表 在数据库内创建的每个对象(约束.默认值.日志.规则.存储过程等)在表中占一行.只有在 tempdb 内,每个临时对象才在该表中占一行. 列名 数据类型 描述 name sys ...

  4. JavaScript操作DOM与jQuyer操作DOM的对比

    1.通过jQuery方法包装后的对象,是一个类数组对象.它与DOM对象完全不同,唯一相似的是它们都能操作DOM. 2.通过jQuery方法包装后的对象,是一个类数组对象.它与DOM对象完全不同,唯一相 ...

  5. C++ 继承/派生、访问属性、构造函数

    1.子类继承父类的继承方式:public,private,protected,不写则默认为private: 2.子类会继承父类的全部成员(除了构造函数.析构函数,虽然析构函数有virtual,但是不是 ...

  6. Day3 CSS 引入及基本选择器

    一 .CSS 层叠样式表,为了使网页元素的样式更加丰富,内容与样式拆分开来.HTML负责结构与内容,表现形式交给CSS. CSS注释/**/ 来注释 二.CSS基本语法与引用 CSS的语法结构 选择器 ...

  7. WPF动画 - Loading加载动画

    存在问题: 最近接手公司一个比较成熟的产品项目开发(WPF桌面端),其中,在登陆系统加载时,60张图片切换,实现loading闪烁加载,快有密集恐惧症了!!! 代码如下: private void L ...

  8. 火狐加载用户配置文件 "C:\XXX\Mozilla Firefox\firefox.exe" http://192.168.1.1:8080 -profile ../kkk

    "C:\XXX\Mozilla Firefox\firefox.exe" http://192.168.1.1:8080 -profile ../kkk $("#clic ...

  9. vue工程化之公有CSS、JS文件

    1.关于公共的css 在src下面新建public.css,然后在main.js中引入进来 import '@/public.css',这样所有页面中都会使用这个样式了,如果只是部分页面需要,那还是不 ...

  10. git 支持tree命令

    由于git 里面是不支持tree命令的 有两种方法可以达到tree的效果 1.使用 winpty tree.com 2.安装tree.exe可执行文件 下载链接: https://sourceforg ...