题目链接 BZOJ

洛谷

区间第k小,我们可以想到主席树。然而这是静态的,怎么支持修改?

静态的主席树是利用前缀和+差分来求解的,那么对于每个位置上的每棵树看做一个点,拿树状数组更新。

还是树状数组的过程,区间加时,每到一个位置在这棵主席树中插入这个数。

查询时,将所有询问要访问到的主席树存下来,delta为所有存下的树的和的差值;改变节点时所有的主席树访问节点都变。

每次树状数组会访问logn棵树,每棵树改变logn个点。时间空间复杂度都为 \(O(nlog^2n)\).

线段树套平衡树见这.

整体二分见这.

//27068kb	364ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define lb(x) (x)&-(x)
const int N=1e4+5,S=N*220,MAXIN=1e5; int n,Q,A[N],cnt,ref[N<<1];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Operation{ //离线离散化
int l,r,K;//l=0:Modify r:pos K:val
Operation() {}
Operation(int l,int r,int k):l(l),r(r),K(k) {}
}q[N];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
namespace T
{
#define lson son[rt][0]
#define rson son[rt][1] int tot,son[S][2],sz[S],root[N],totl,totr,ql[N],qr[N];
void Insert(int &rt,int l,int r,int p,int v)
{
if(!rt) rt=++tot;
sz[rt]+=v;//既然直接在自己这棵树上改,不需要再复制很多重复节点。
if(l<r){
int m=l+r>>1;
if(p<=m) Insert(lson,l,m,p,v);
else Insert(rson,m+1,r,p,v);
}
}
void Modify(int p,int v,int delta){
while(p<=n)
Insert(root[p],1,cnt,v,delta),p+=lb(p);
}
int Query(int l,int r,int k)
{
if(l==r) return ref[l];
int delta=0;
for(int i=1; i<=totl; ++i) delta-=sz[son[ql[i]][0]];
for(int i=1; i<=totr; ++i) delta+=sz[son[qr[i]][0]];
if(delta>=k){
for(int i=1; i<=totl; ++i) ql[i]=son[ql[i]][0];
for(int i=1; i<=totr; ++i) qr[i]=son[qr[i]][0];
return Query(l,l+r>>1,k);
}
else{
for(int i=1; i<=totl; ++i) ql[i]=son[ql[i]][1];
for(int i=1; i<=totr; ++i) qr[i]=son[qr[i]][1];
return Query((l+r>>1)+1,r,k-delta);
}
}
int Kth(int l,int r,int k)
{//别忘l-1.
totl=totr=0;
for(--l; l; l^=lb(l)) ql[++totl]=root[l];//存根。
for(; r; r^=lb(r)) qr[++totr]=root[r];
return Query(1,cnt,k);
}
}
inline char Get(){
char c=gc();while(c!='Q'&&c!='C') c=gc();
return c;
}
int Find(int x)
{
int l=1,r=cnt,mid;
while(l<r)
if(ref[mid=l+r>>1]<x) l=mid+1;
else r=mid;
return l;
} int main()
{
n=read(),Q=read();
for(int i=1; i<=n; ++i) ref[i]=A[i]=read();
int t=n;
for(int l,r,k,i=1; i<=Q; ++i)
if(Get()=='Q') l=read(),r=read(),k=read(), q[i]=Operation(l,r,k);
else r=read(),k=read(), q[i]=Operation(0,r,k),ref[++t]=k; std::sort(ref+1,ref+1+t), cnt=1;
for(int i=2; i<=t; ++i)
if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i]; for(int i=1; i<=n; ++i) T::Modify(i,A[i]=Find(A[i]),1);
for(int i=1; i<=Q; ++i)
if(!q[i].l) T::Modify(q[i].r,A[q[i].r],-1), T::Modify(q[i].r,A[q[i].r]=Find(q[i].K),1);
else printf("%d\n",T::Kth(q[i].l,q[i].r,q[i].K));
return 0;
}

BZOJ.1901.Dynamic Rankings(树状数组套主席树(动态主席树))的更多相关文章

  1. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  2. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  3. bzoj 1901 Dynamic Rankings (树状数组套线段树)

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

  4. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  5. BZOJ 1901 Zju2112 Dynamic Rankings 树状数组套线段树

    题意概述:带修改求区间第k大. 分析: 我们知道不带修改的时候直接上主席树就可以了对吧?两个版本号里面的节点一起走在线段树上二分,复杂度是O((N+M)logN). 然而这里可以修改,主席树显然是凉了 ...

  6. 【BZOJ 1901】Zju2112 Dynamic Rankings &&【COGS 257】动态排名系统 树状数组套线段树

    外面是树状数组,里面是动态开点线段树,对于查询我们先把有关点找出来,然后一起在线段树上行走,这样就是单个O(log2)的了 #include <cstdio> #include <v ...

  7. BZOJ 1901 Dynamic Rankings (整体二分+树状数组)

    题目大意:略 洛谷传送门 这道题在洛谷上数据比较强 貌似这个题比较常见的写法是树状数组套主席树,动态修改 我写的是整体二分 一开始的序列全都视为插入 对于修改操作,把它拆分成插入和删除两个操作 像$C ...

  8. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

  9. Dynamic Rankings(树状数组套权值线段树)

    Dynamic Rankings(树状数组套权值线段树) 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[ ...

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

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

随机推荐

  1. mybatis dao 层开发简易版 非整合 spring

    同样老习惯,先上项目结构截图 首先 补充上篇文中缺失的 mysql demo 用的 小脚本 drop database if exists mybatis; CREATE DATABASE `myba ...

  2. Python 算法实现

    # [程序1] # 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? l=[1,2,3,4] count = 0 for i in range(len(l)): fo ...

  3. 原生JavaScript技巧大收集(1~10)

    1.原生JavaScript实现字符串长度截取 01 function cutstr(str, len) { 02     var temp; 03     var icount = 0; 04    ...

  4. G - DNA sequence HDU - 1560

    题目链接: https://vjudge.net/contest/254151#problem/G AC代码: #include<iostream> #include<cstring ...

  5. Comparable和Comparator的区别&Collections.sort的两种用法

    在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...

  6. python3之模板pycurl探测web服务质量

    1.pycurl简介 pycURL是libcurl多协议文件传输库的python接口,与urllib模块类似,PycURL可用于从python程序中获取由URL标识的对象,功能很强大,libcurl速 ...

  7. Number of Airplanes in the Sky

    Given an interval list which are flying and landing time of the flight. How many airplanes are on th ...

  8. 使用maven命令终端构建一个web项目及发布该项目

    构建环境: maven版本:3.3.9 系统平台:Windows7 x64 JDK版本:1.7 构建步骤: 1.打开maven安装目录,在地址栏输入cmd进入命令窗口 2.输入命令mvn archet ...

  9. poj1292

    prim,把每个墙看成一个节点,从起点用prim求最小生成树,直到覆盖到终点为止,输出最小生成树中的最大边 #include <cstdio> #include <cmath> ...

  10. LINUX下IDEA等工具调试项目时提示:Unable to open debugger port

    在Ubuntu下调试项目时使用TOMCAT容器,在设置好相应的TOMCAT LOCAL 路径及相关信息后,点击调试项目出现: Unable to open debugger port : java.n ...