题目链接 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. Python内置函数之匿名(lambda)函数

    Python内置函数之匿名(lambda)函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.匿名函数 #!/usr/bin/env python #_*_coding:utf ...

  2. Spark记录-Scala数组

    Scala提供了一种数据结构叫作数组,数组是一种存储了相同类型元素的固定大小顺序集合.数组用于存储数据集合,但将数组视为相同类型变量的集合通常更为有用. 可以声明一个数组变量,例如:numbers,使 ...

  3. [软件]Xcode查找系统framework所在路径

    有的时候, 我们不小心改了头文件, 导致Xcode系统库被修改(改回去也不行) 假设我改的是UIKit.framework类库里面的一个文件, 那么你只需要从另一个好使的电脑上, 在这个路径找到UIK ...

  4. Sublime Text 3 绿色汉化版 x64

    之前做了<Sublime Text 2 绿色汉化版 x64>,这些天抽空做了下 ST3 的汉化.. 果然我没有任何理由爱上 ST3,不仅pojie麻烦,而且汉化更麻烦,菜单字符长度做了限制 ...

  5. 用Canvas做动画

    之前看过不少HTML5动画的书,讲解的是如何去做,对于其中的数学原理讲解的不详细,常有困惑.最近看的<HTML5+JavaScript 动画基础>这个是译本,Keith Peters曾写过 ...

  6. BZOJ4103 异或运算

    4103: [Thu Summer Camp 2015]异或运算 Time Limit: 20 Sec  Memory Limit: 512 MB Description 给定长度为n的数列X={x1 ...

  7. 加速计 & CoreMotion

    CHENYILONG Blog 加速计 & CoreMotion 加速计 & CoreMotion 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微 ...

  8. 第11月第23天 markedTextRange 崩溃

    1. 在对textView.textField限制文字长度时,如果不做特殊处理,当联想文字加上已输入文字超出设定长度时,iOS 7.0系统会崩溃(ios 8.0以上系统做了处理,不会崩溃). http ...

  9. 第5月第24天 线性变换 opengl

    1. http://news.qiyeku.com/news_837979.html 2. opengl + (Class)layerClass { return [CAEAGLLayer class ...

  10. Servlet笔记11--补充

    Servlet线程安全问题: 代码示例: package com.bjpowernode.javaweb.servlet; import java.io.IOException; import jav ...