【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题
达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360
说一下我对这个模板的理解:
看到这个方法很容易不知所措,因为动态K值需要套树状数组,而我一开始根本不知道该怎么套,,
学习吧,,,
然后我自己脑补如果不套会如何?后来想到是查询O(logn),修改是O(nlogn),很明显修改的复杂度太大了,为了降低修改的复杂度,我们只得套上树状数组来维护前缀和使它的n的复杂度降低为logn,从而修改的复杂度变为O(log2n)。但因为我们套了树状数组,所以查询的复杂度也不得不上升到O(log2n),但从整体上看来这些牺牲是值得的,总复杂度最终是O(nlog2n)。
这些都太简单了是吧,,果然我太傻,,
比较的时候和普通的主席树不同,不再是两个做差了,而是把树状数组中的节点放到两个池子里做差,我的code里是L和R两个池子,,
至于为什么要离线,我思考了很久,,,问过达神,,,并不理解,,,继续思考,,,后来明白是为了找到所有序列中出现的数的最大值,这样才能建树啊,,,然后得出结论:我太傻以至于马上就要滚粗了,,,TAT
最后向iwtwiioi寻求帮助,知道自己错误的原因是数组开的太小了,,
达神也帮我开大过,不过貌似太大炸了导致每次都是TLE或WA,,
还是得注意细节啊,这道题一个晚上才写出了模板,我果然太弱了。
#include<cstdio>
#include<algorithm>
#define lowbit(x) (x&-x)
#define read(x) x=getint()
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
using namespace std;
const int N=10010;
inline const int getint(){char c=getchar();int k=1,r=0;for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
struct node{int l,r,s;}T[N*300];
int n,m,cl,cr,tot=0,num=0,cnt=0,ans[N<<1],root[N],a[N],L[N],R[N],QL[N],QR[N],K[N];
inline void update(const int &l,const int &r,int &pos,const int &k,const int &sz){
T[++tot]=T[pos]; pos=tot; T[pos].s+=sz;
if (l==r) return; int mid=(l+r)>>1;
if (k<=mid) update(l,mid,T[pos].l,k,sz); else update(mid+1,r,T[pos].r,k,sz);
}
inline void addd(int x,const int &k,const int &sz){for(;x<=n;x+=lowbit(x)) update(1,num,root[x],k,sz);}
inline int query(const int &l,const int &r,const int &k){
if (l==r) return l;
int suml=0,sumr=0;
for1(i,1,cl) suml+=T[T[L[i]].l].s;
for1(i,1,cr) sumr+=T[T[R[i]].l].s;
int mid=(l+r)>>1;
if (k<=sumr-suml){
for1(i,1,cl) L[i]=T[L[i]].l;
for1(i,1,cr) R[i]=T[R[i]].l;
return query(l,mid,k);
}else{
for1(i,1,cl) L[i]=T[L[i]].r;
for1(i,1,cr) R[i]=T[R[i]].r;
return query(mid+1,r,k-sumr+suml);
}
}
inline int getans(int l,int r,const int &k){
for(cl=0;l>0;l-=lowbit(l)) L[++cl]=root[l];
for(cr=0;r>0;r-=lowbit(r)) R[++cr]=root[r];
return query(1,num,k);
}
int main(){
read(n); read(m); char c;
for1(i,1,n) read(a[i]),ans[++cnt]=a[i];
for1(i,1,m){
for(c=getchar();c<'A'||c>'Z';c=getchar());
read(QL[i]); read(QR[i]);
if (c=='Q') read(K[i]);
else ans[++cnt]=QR[i];
}sort(ans+1,ans+cnt+1);
ans[cnt+1]=1E9+10;
for1(i,1,cnt) if (ans[i]!=ans[i+1]) ans[++num]=ans[i];
for1(i,1,n) a[i]=lower_bound(ans+1,ans+num+1,a[i])-ans;
for1(i,1,n) addd(i,a[i],1);
for1(i,1,m){
if (K[i]) printf("%d\n",ans[getans(QL[i]-1,QR[i],K[i])]);
else{
addd(QL[i],a[QL[i]],-1);
a[QL[i]]=lower_bound(ans+1,ans+num+1,QR[i])-ans;
addd(QL[i],a[QL[i]],1);
}
}return 0;
}
然后就可以了。这是DaD3zZ几年前就随手虐的东西,本蒟蒻还得继续努力呀~~~
【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题的更多相关文章
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解
题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...
- P2617 Dynamic Rankings(树状数组套主席树)
P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...
- LUOGU P2617 Dynamic Rankings(树状数组套主席树)
传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...
- [COGS257]动态排名系统 树状数组套主席树
257. 动态排名系统 时间限制:5 s 内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- BZOJ 2141 排队(树状数组套主席树)
解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...
- BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t 要求你把第i个数修改为t 题解 动态的区间第k ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...
- 【树状数组套主席树】带修改区间K大数
P2617 Dynamic Rankings 题目描述给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+ ...
随机推荐
- TestNG之执行顺序
如果很有个测试方法,并且这几个方法又有先后顺序,那么如果让TestNG按照自己想要的方法执行呢 一.通过Dependencies 1.在测试类中添加Dependencies @Test public ...
- Head First HTML5 Programming 读书笔记
1:HTML5引入了简单化的标记,新的语义和媒体元素,另外要依赖于一组支持web应用的js库. 2:关于js 对象是属性的结合 window对象是全局变量. document对象是window的一个属 ...
- 2014 Super Training #8 A Gears --并查集
题意: 有N个齿轮,三种操作1.操作L x y:把齿轮x,y链接,若x,y已经属于某个齿轮组中,则这两组也会合并.2.操作Q x y:询问x,y旋转方向是否相同(等价于齿轮x,y的相对距离的奇偶性). ...
- ZOJ 3659 & HDU 4424 Conquer a New Region (并查集)
这题要用到一点贪心的思想,因为一个点到另一个点的运载能力决定于其间的边的最小权值,所以先把线段按权值从大到小排个序,每次加的边都比以前小,然后合并集合时,比较 x = findset(a) 做根或 y ...
- 学习web前端三个月感悟
总结一下自己学习前端三个月的进步和不足: 其实也算机遇,开学时,便有一个PHP培训,只记得当时拿到培训课程的时候,第一感觉就是 好难,什么留言板制作,学生信息系统的制作,navicat和PHP结合使用 ...
- MySQL数据库学习笔记(六)----MySQL多表查询之外键、表连接、子查询、索引
本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...
- android调试模拟器启动太慢,怎样才能更快的调试程序呢?
答: 1. 模拟器不关,直接按调试按钮系统会自动重新安装软件的.
- Java常用类库——Runtime
runtime运行时候,是封装了一个JVM进程的类,每一个JAVA程序实际上启动了一个JVM进程,那么每个JVM对应一个runtime实例.此实例是由JVM为其实例化. 本类的定义中没有构造方法,因为 ...
- Window.open()方法参数详解
Window.open()方法参数详解 1, 最基本的弹出窗口代码 window.open('page.html'); 2, 经过设置后的弹出窗口 window.open('page.html ...
- 关于RACK的一点简单介绍
0 前言 如有错误欢迎指出,如需转载,请注明原文链接. 1 Rack是什么 一句话介绍,Rack是一个Web接口,定义了一系列的标准,具体实现的工作是交给服务器(puma, thin等)做的. 如果你 ...